Доброго времени суток. Хочу сделать "мост" между wifi и Dali. За основу взял код: https://habr.com/ru/post/321888/ Для теста все прошил и залил в Arduino nano и ожидаемо все хорошо, все работает. Для ESP же есть проблема - не могу получить статус светильника, падает в ошибку Exception 9: LoadStoreAlignmentCause: Load or store to an unaligned address, ругается на строчку в файле Dali.cpp: timeArray[k] = timeArray[k — 1]. Что я пытался сделать — с помощью sizeof выяснил, сколько занимают типы данных в atmega328 и в esp8266. Ну и в итоге поменял все int на int16_t и с другими типами также. Но это не помогло. Однако заметил, если в файле Dali.cpp в строке: int16_t timeArray[arrLength] жестко указать размер массива [20], а не [arrLength] то тогда ошибка не появляется, но функция всегда возвращает значение 255. Прикрепляю исходники, может кто подскажет.
/* Timer 2 in the ATMega328 and Timer 1 in a ATtiny85 is used to find the time between each transition coming from the demodulation circuit. Their setup is for sampling the input in regular intervals. For practical reasons we use power of 2 timer prescaller for sampling, for best timing we use pulse lenght as integer multiple of sampling speed. We chose to sample every 8 ticks, and pulse lenght of 48 ticks thats 6 samples per pulse, lower sampling rate (3) will not work well for innacurate clocks (like internal oscilator) higher sampling rate (12) will cause too much overhead and will not work at higher transmission speeds. This gives us 16000000Hz/48/256 = 1302 pulses per second (so it's not really 1200) At different transmission speeds or on different microcontroller frequencies, clock prescaller is adjusted to be compatible with those values. We allow about 50% clock speed difference both ways allowing us to transmit even with up to 100% in clock speed difference */
class Dali { public: Dali(); //the constructor void setTxPin(uint8_t pin); //set the arduino digital pin for transmit. void setRxAnalogPin(uint8_t pin); //set the arduino digital pin for receive. void workAround1MhzTinyCore(uint8_t a = 1); //apply workaround for defect in tiny Core library for 1Mhz void setupTransmit(uint8_t pin); //set up transmission void setupAnalogReceive(uint8_t pin); void transmit(uint8_t cmd1, uint8_t cmd2); //transmit 16 bits of data void scanShortAdd(); //scan for short address void busTest(); // bus test void initialisation(); //initialization of new luminaries bool cmdCheck(String & input, int16_t & cmd1, int16_t & cmd2); uint8_t receive(); //get response
uint8_t speedFactor; uint16_t delay1; uint16_t delay2; uint16_t period; String errorMsg; //error message of last operation bool msgMode; //0 - get only response from dali bus to COM; 1 - response with text (comments) bool getResponse; uint8_t RxAnalogPin;
long daliTimeout = 20000; //us, DALI response timeout int16_t analogLevel = 870; //analog border level (less - "0"; more - "1")
private:
void sendByte(uint8_t b); //transmit 8 bits of data void sendBit(int16_t b); //transmit 1 bit of data void sendZero(void); //transmit "0" void sendOne(void); //transmit "1" void splitAdd(long input, uint8_t &highbyte, uint8_t &middlebyte, uint8_t &lowbyte); //split random address
void Dali::setTxPin(uint8_t pin) { TxPin = pin; // user sets the digital pin as output pinMode(TxPin, OUTPUT); digitalWrite(TxPin, HIGH); }
void Dali::setRxAnalogPin(uint8_t pin) { RxAnalogPin = pin; // user sets the digital pin as output }
void Dali::workAround1MhzTinyCore(uint8_t a) { applyWorkAround1Mhz = a; }
void Dali::setupAnalogReceive(uint8_t pin) { setRxAnalogPin(pin); // user sets the analog pin as input }
void Dali::setupTransmit(uint8_t pin) { setTxPin(pin); speedFactor = 2; //we don't use exact calculation of passed time spent outside of transmitter //because of high ovehead associated with it, instead we use this //emprirically determined values to compensate for the time loss
#if F_CPU == 1000000UL uint16_t compensationFactor = 88; //must be divisible by 8 for workaround #elif F_CPU == 8000000UL uint16_t compensationFactor = 12; #else //16000000Mhz uint16_t compensationFactor = 4; #endif
#if F_CPU == 1000000UL delay2 -= 22; //22+2 = 24 is divisible by 8 if (applyWorkAround1Mhz) { //definition of micro delay is broken for 1MHz speed in tiny cores as of now (May 2013) //this is a workaround that will allow us to transmit on 1Mhz //divide the wait time by 8 delay1 >>= 3; delay2 >>= 3; } #endif #endif }
void Dali::transmit(uint8_t cmd1, uint8_t cmd2) // transmit commands to DALI bus (address byte, command byte) { sendBit(1); sendByte(cmd1); sendByte(cmd2); digitalWrite(TxPin, HIGH); }
void Dali::sendByte(uint8_t b) { for (int16_t i = 7; i >= 0; i--) { sendBit((b >> i) & 1); } }
void Dali::sendBit(int16_t b) { if (b) { sendOne(); } else { sendZero(); } }
void Dali::busTest() //DALI bus test { int16_t maxLevel; int16_t minLevel;
//Luminaries must turn on and turn off. If not, check connection. delay(100); dali.transmit(BROADCAST_C, OFF_C); //Broadcast ON delay(500); dali.transmit(BROADCAST_C, ON_C); //Broadcast OFF delay(100); //while (!Serial); // wait for serial port to connect. Needed for native USB port only
//Receive response from luminaries: max and min level dali.transmit(BROADCAST_C, QUERY_STATUS); maxLevel = dali.maxResponseLevel();
if (input.length() != 16) { test = false; //check if command contain 16bit } else { for (int16_t i = 0; i <= input.length() - 1; i++) { if ((int16_t)input.charAt(i) == 49 or (int16_t)input.charAt(i) == 48) {} else { test = false; }; }; };
Хоть и старая тема, но когда вы создаёте массив (он не динамический), потому ему нужно жестко задавать количество элементов, а вы передаёте ему переменную в качестве количества элементов, вот и ругается. Какая функция возвращает 255 тоже неясно, разбирать весь код нет желания.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения