Всем привет!
Есть код, в теле которого есть прерывание по uart
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
//if (inChar == 'a') {
stringComplete = true;
}
}
}
заливаю этот код в нано - все отлично работает.
Заливаю его же без каких-либо вообще изменений в мегу - не работает.
Может какие-то аппаратные особенности? подключено все верно.
Пардон, это конечно кусок кода.
Я не знаю, нужен ли весь код. Выложу чуть ниже.
Суть такая: собрал, отлаживал на нано. Нано связана с одноплатником на линуксе по уарту.
все работает. все отлично.
Спаял готовый образец (на меге) - она ничего не принимает…почему?
может быть какая-то аппаратная несовместимость?
одноплатник работает от 3.3В , те логический уровень = 1 = 3.3в на пине. может этого мало меге?
код:
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
byte id01 = 0; //Переменная температуры нагрева при косвенном нагреве
byte id02 = 0; //Переменная температуры включения косвенного нагрева
bool id03 = 0; //Использовать косвенный нагрев
bool id04 = 0; //Запрет косвенного нагрева
byte id05 = 0; //Переменная температура нагрева при электронагреве
bool id06 = 0; //Использовать электронагрев
bool id07 = 0; //Использовать таймер
byte id08 = 0; //Таймер включения электронагрева
byte id09 = 0; //Таймер выключения электронагрева
byte id10 = 0; //Температура включения рециркуляции
bool id11 = 0; //Использовать рециркуляцию при работе электронагрева
bool id12 = 0; //Использовать таймер для рециркуляции
byte id13 = 0; //Таймер включения рециркуляции
byte id14 = 0; //Таймер выключения рециркуляции
byte id15 = 0; //Установка текущего времени
byte id16 = 0; //пароль
bool id17 = 0;
bool id18 = 0; //Флаг работы косвенного нагрева
bool id19 = 0; //Флаг работы электронагрева
bool id20 = 0; //Флаг работы косвенного нагрева
bool id21 = 0; //Кнопка СТОП режим работы
bool id22 = 0; //Кнопка АВТОМАТ режим работы
bool id23 = 0; //Кнопка ЭЛЕКТРО режим работы
bool id24 = 0; //Кнопка КОВЕННЫЙ режим работы
bool id25 = 0; //Кнопка СТОП рециркуляция
bool id26 = 0; //Кнопка АВТОМАТ рециркуляция
bool id27 = 0; //Кнопка ВКЛ рециркуляция
byte id28 = 0; //Температура воды в бойлере
byte id29 = 0; //Температура теплоносителя
byte id30 = 0; //Влажность воздуха
byte id31 = 0; //Температура воздуха
byte H_Sta_REC = 0; //Часы запуска рециркуляции
byte M_Sta_REC = 0; //минуты запуска рециркуляции
byte H_Sto_REC = 0; //Часы стоп рециркуляции
byte M_Sto_REC = 0; //минуты стоп рециркуляции
bool REC_Timer = 0; //Флаг включения таймера рециркуляции
bool REC_Timer_FLAG = 0; //Флаг срабатывания таймера рециркуляции
bool REC = 0; //Флаг включения рециркуляции
bool REC_TEN_FLAG = 0; //флаг работы рециркуляции при работе от электротэна
bool REC_Temp_FLAG = 0; //флаг работы рециркуляции при работе от температуры воды
byte H_Sta_TEN = 0; //Часы запуска нагрева ТЭНом
byte M_Sta_TEN = 0; //минуты запуска нагрева ТЭНом
byte H_Sto_TEN = 0; //Часы стоп нагрева ТЭНом
byte M_Sto_TEN = 0; //минуты стоп нагрева ТЭНом
bool TEN_Timer = 0; //Флаг включения таймера нагрева ТЭНом
bool TEN_Timer_FLAG = 0; //Флаг срабатывания таймера нагрева ТЭНом
bool TEN = 0; //Флаг включения нагрева ТЭНом
bool TEN_Temp_FLAG = 0; //флаг работы нагрева ТЭНом при работе от температуры воды
bool TEN_E = 0; //флаг работы
bool TEN_FLAG = 0; //флаг работы
byte Water_T = 0; //текущая температура воды в бойлере
bool Zotta = 0; //флаг работы электрокотла
byte H_Sta_EL = 0; //Часы запуска электронагревателя
byte M_Sta_EL = 0; //минуты запуска электронагревателя
byte H_Sto_EL = 0; //Часы стоп электронагревателя
byte M_Sto_EL = 0; //минуты стоп электронагревателя
byte Hour = 0; //текущее время, часы
byte Min = 0; //текущее время, минуты
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
//"$##*99I01*02T22:23*22I99999*33I12345678*"
if (stringComplete) { //Если строка принята, то выполняем ее разбор
char inputBuffer[inputString.length()]; //Создаем массив символов, длинной = длинепринятой строки
inputString.toCharArray(inputBuffer, inputString.length()); //Преобразуем строку в массив
char *str; //создадим ссылку str на массив символов
char *buf = inputBuffer; //создадим ссылку buf на массив символов inputBuffer
while ((str = strtok_r(buf, "*", &buf)) != NULL) //разбираем принятую строку по разделителю *
{
//Serial.println(str);
if (str[2]=='I'){ //проверка принятого блока на то, что принятые данные - число
byte n = 3; //переменная, обозначающая какой символ по счету в полученной строке является символом-разделителем (I)
char* DATA = str + n; //Указатель на массив DATA начинающийся с n-го символа массива str
byte input_id = atoi(str); //Преобразуем массив символов ID в число и присваем это число переменной input_id
uint16_t input_data = atoi(DATA); //преобразование массива DATA в число и присвоение его переменной input_data. Для значений менее 32 767 использовать uint16_t input_data = atoi(DATA);
if ((1<=input_id<=99)&&(0<=input_data<=9999)) //проверяем, попадают ли принятые данные допустимые пределы
{
if((input_id==1)&&(id01!=input_data)&&(30<=input_data)&&(input_data<=85)){id01=input_data;}else{if((input_id==1)&&(input_data<=30)){id01=30;}else{if((input_id==1)){id01=85;};};};
if((input_id==2)&&(id02!=input_data)&&(30<=input_data)&&(input_data<=85)){id02=input_data;}else{if((input_id==2)&&(input_data<=30)){id02=30;}else{if((input_id==2)){id02=85;};};};
if((input_id==3)&&(id03!=input_data)){id03=input_data;};
if((input_id==4)&&(id04!=input_data)){id04=input_data;};
if((input_id==5)&&(id05!=input_data)){id05=input_data;};
if((input_id==6)&&(id06!=input_data)){id06=input_data;};
if((input_id==7)&&(id07!=input_data)){id07=input_data;};
if((input_id==8)&&(id08!=input_data)){id08=input_data;};
if((input_id==9)&&(id09!=input_data)){id09=input_data;};
if((input_id==10)&&(id10!=input_data)){id10=input_data;};
if((input_id==11)&&(id11!=input_data)){id11=input_data;};
if((input_id==12)&&(id12!=input_data)){id12=input_data;};
if((input_id==13)&&(id13!=input_data)){id13=input_data;};
if((input_id==14)&&(id14!=input_data)){id14=input_data;};
if((input_id==15)&&(id15!=input_data)){id15=input_data;};
if((input_id==16)&&(id16!=input_data)){id16=input_data;};
if((input_id==21)&&(id21!=input_data)&&(input_data==1)){id21=input_data;id22=0;id23=0;id24=0;}; //обработка нажатия кнопки СТОП нагрев воды
if((input_id==22)&&(id22!=input_data)&&(input_data==1)){id22=input_data;id21=0;id23=0;id24=0;}; //обработка нажатия кнопки АВТОМАТ нагрев воды
if((input_id==23)&&(id23!=input_data)&&(input_data==1)){id23=input_data;id21=0;id22=0;id24=0;}; //обработка нажатия кнопки ЭЛЕКТРО нагрев воды
if((input_id==24)&&(id24!=input_data)&&(input_data==1)){id24=input_data;id21=0;id22=0;id23=0;}; //обработка нажатия кнопки КОСВЕННЫЙ нагрев воды
if((input_id==25)&&(id25!=input_data)&&(input_data==1)){id25=input_data;id26=0;id27=0;}; //обработка нажатия кнопки СТОП рециркуляции
if((input_id==26)&&(id26!=input_data)&&(input_data==1)){id26=input_data;id25=0;id27=0;}; //обработка нажатия кнопки АВТОМАТ рециркуляции
if((input_id==27)&&(id27!=input_data)&&(input_data==1)){id27=input_data;id25=0;id26=0;}; //обработка нажатия кнопки ВКЛ рециркуляции
};
/*
Serial.print("id=");
Serial.println(input_id);
Serial.print("DATA=");
Serial.println(input_data);
Serial.println(" ");
} else {Serial.println(" ");};*/
};
if ((str[2]=='T') && (str[5] == ':')){ //проверка принятого блока на то, что принятые данные - время
byte n = 3; //переменная, обозначающая какой символ по счету в полученной строке является символом-разделителем (T)
byte m = 6; //переменная, обозначающая какой символ по счету в полученной строке является символом-разделителем (:) часов и минут
char* HOUR = str + n; //Указатель на массив HOUR начинающийся с n-го символа массива str для хранения часов
char* MIN = str + m; //Указатель на массив HOUR начинающийся с n-го символа массива str для хранения часов
byte input_id = atoi(str); //Преобразуем массив символов ID в число и присваем это число переменной input_id
uint16_t hour_data = atoi(HOUR); //преобразование массива DATA в число и присвоение его переменной input_data. Для значений менее 32 767 использовать uint16_t input_data = atoi(DATA);
uint16_t min_data = atoi(MIN); //преобразование массива DATA в число и присвоение его переменной input_data. Для значений менее 32 767 использовать uint16_t input_data = atoi(DATA);
if ((1<=input_id<=99)&&(0<=hour_data<=24)&&(0<=min_data<=24)) //проверяем, попадают ли принятые данные допустимые пределы
{
};
/*
Serial.print("id=");
Serial.println(input_id);
Serial.print("Часы=");
Serial.println(hour_data);
Serial.print("Минуты=");
Serial.println(min_data);
Serial.println(" ");*/
} else {/*Serial.println(" ");*/};
}
//!!!Блок обработки таймера нагрева от ТЭНА---------------------------------------------------------------------------------------------
if(H_Sta_TEN > H_Sto_TEN){
if((Hour == H_Sta_TEN)&&(Min < H_Sta_TEN)){TEN_Timer = 0;}
else{
if((Hour < H_Sta_TEN)&&(Hour>H_Sto_TEN)){TEN_Timer = 0;}
else{
if((Hour == H_Sto_TEN)&&(Min >= H_Sto_TEN)){TEN_Timer = 0;}else{TEN_Timer = 1;};
};
};
}
else{
if(H_Sta_TEN < H_Sto_TEN){
if((Hour == H_Sta_TEN)&&(Min >= H_Sta_TEN)){TEN_Timer = 1;}
else{
if((Hour > H_Sta_TEN)&&(Hour < H_Sto_TEN)){TEN_Timer = 1;}
else{
if((Hour == H_Sto_TEN)&&(Min < H_Sto_TEN)){TEN_Timer = 1;}else{TEN_Timer = 0;};
};
};
}
else{
if(H_Sta_TEN == H_Sto_TEN){
if(M_Sta_TEN < M_Sto_TEN){
if((Min >= M_Sta_TEN)&&(Min < M_Sto_TEN)&&(Hour == H_Sta_TEN)){TEN_Timer = 1;}else{TEN_Timer = 0;};
};
if(M_Sta_TEN > M_Sto_TEN){
if((Min < M_Sta_TEN)&&(Min >= M_Sto_TEN)&&(Hour == H_Sta_TEN)){TEN_Timer = 0;}else{TEN_Timer = 1;};
};
if (M_Sta_TEN == M_Sto_TEN){
TEN_Timer=0;
};
};
};
};
//!!!конец блока обработки таймера нагрева от ТЭНА----------------------------------------------------------------------------------------
//!!!Блок обработки таймера рециркуляции--------------------------------------------------------------------------------------------------
if(H_Sta_REC > H_Sto_REC){
if((Hour == H_Sta_REC)&&(Min < H_Sta_REC)){REC_Timer = 0;}
else{
if((Hour < H_Sta_REC)&&(Hour>H_Sto_REC)){REC_Timer = 0;}
else{
if((Hour == H_Sto_REC)&&(Min >= H_Sto_REC)){REC_Timer = 0;}else{REC_Timer = 1;};
};
};
}
else{
if(H_Sta_REC < H_Sto_REC){
if((Hour == H_Sta_REC)&&(Min >= H_Sta_REC)){REC_Timer = 1;}
else{
if((Hour > H_Sta_REC)&&(Hour < H_Sto_REC)){REC_Timer = 1;}
else{
if((Hour == H_Sto_REC)&&(Min < H_Sto_REC)){REC_Timer = 1;}else{REC_Timer = 0;};
};
};
}
else{
if(H_Sta_REC == H_Sto_REC){
if(M_Sta_REC < M_Sto_REC){
if((Min >= M_Sta_REC)&&(Min < M_Sto_REC)&&(Hour == H_Sta_REC)){REC_Timer = 1;}else{REC_Timer = 0;};
};
if(M_Sta_REC > M_Sto_REC){
if((Min < M_Sta_REC)&&(Min >= M_Sto_REC)&&(Hour == H_Sta_REC)){REC_Timer = 0;}else{REC_Timer = 1;};
};
if (M_Sta_REC == M_Sto_REC){
REC_Timer=0;
};
};
};
};
//!!!конец блока обработки таймера рециркуляции--------------------------------------------------------------------------------------------------
//!!!Блок обработки логики рециркуляции----------------------------------------------------------------------------------------------------------
if(id25==1){ //id25 - кнопка СТОП рециркуляции
REC = 0; //остановить рециркуляцию
}
else{ if(id27==1){ //id27 - кнопка ВКЛ рециркуляции
REC = 1; //включить рециркуляцию
}
else{ if(id26==1){ //Код при работе в автомате id11 - работа при электронагрева
if (id11 == 1){REC_TEN_FLAG = TEN_FLAG;}else{REC_TEN_FLAG = 1;}; // опция работать или нет при нагреве воды ТЭНом
if (id12 == 1){REC_Timer_FLAG=REC_Timer;}else{REC_Timer_FLAG = 1;}; // опция учитывать таймер рециркуляции
if (id10 >= Water_T){REC_Temp_FLAG = 1;}else{REC_Temp_FLAG = 0;}; // опция работы при температуре выше температуры воды
if (REC_TEN_FLAG && REC_Timer_FLAG && REC_Temp_FLAG){REC = 1;}else{REC = 0;};
};
};
};
//!!!Конец блока обработки логики рециркуляции---------------------------------------------------------------------------------------------------
id30 = random(100);
Serial.print("$$*"); //отправляем символ начала строки
Serial.print(id01);
Serial.print("*");
Serial.print(id02);
Serial.print("*");
Serial.print(id03);
Serial.print("*");
Serial.print(id04);
Serial.print("*");
Serial.print(id05);
Serial.print("*");
Serial.print(id06);
Serial.print("*");
Serial.print(id07);
Serial.print("*");
Serial.print(id08);
Serial.print("*");
Serial.print(id09);
Serial.print("*");
Serial.print(id10);
Serial.print("*");
Serial.print(id11);
Serial.print("*");
Serial.print(id12);
Serial.print("*");
Serial.print(id13);
Serial.print("*");
Serial.print(id14);
Serial.print("*");
Serial.print(id15);
Serial.print("*");
Serial.print(id16);
Serial.print("*");
Serial.print(id17);
Serial.print("*");
Serial.print(id18);
Serial.print("*");
Serial.print(id19);
Serial.print("*");
Serial.print(id20);
Serial.print("*");
Serial.print(id21);
Serial.print("*");
Serial.print(id22);
Serial.print("*");
Serial.print(id23);
Serial.print("*");
Serial.print(id24);
Serial.print("*");
Serial.print(id25);
Serial.print("*");
Serial.print(id26);
Serial.print("*");
Serial.print(id27);
Serial.print("*");
Serial.print(id28);
Serial.print("*");
Serial.print(id29);
Serial.print("*");
Serial.print(id30);
Serial.println("*");
Serial.println(inputString);
inputString ="";
stringComplete = false;
};
}
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
//if (inChar == 'a') {
stringComplete = true;
}
}
}
код рабочий и проверенный, хоть и в разарботке.
если его скомпилировать и открыть монитор порта и далее ввести в поле ввода $$#* и нажать энтер, то программа выдаст ответ.
по какой-то причине мега не принимает запрос.
может быть сигнал с амплитудой 3.3В для меги мало?
Большая скорость 115200? (хотя нормальная)
Ребята, да какая разница - уже поняли, что все ок с кодом.
Сейчас установил, что с меги на уарт одноплатника все приходит.
Получается, что мега не видит запрос. остается только версия с 3.3в, которые мега не воспринмиает? кто как думает? кто сталкивался с подобным?
суть прогаммы такая: ардуина получает запрос и как только его получила - отправляет ответ. те без полученного запроса - ответа - нет.
в качестве одноплатника - оранж пи зеро. на нем вэбсервер и на нем есть контроль принятой строки, те ответа от ардуины. пока все в процессе отладки.
прошиваю этот код в нано - подключаю к оранжу, и они сразу начинают отлично общаться - запрос - ответ. те как надо. можно параллельно открыть монитор порта и на нем будет видно: запрос-ответ.
прошиваю в мегу - и тишина. запрос не приходит, соответсвенно ответа - нет. в мониторе порта принудительно начинаю вводить запросы (эмулирую оранж) и она отвечает. ответ виден на оранж.
так Вы никогда не отладитесь. У Вас проблема с чем? С serialEvent? Так наюха в Вашем коде всё остальное, что а) сбивает с толку; б) мешает восприятию; в) может как-то влиять.
Когда возникает проблема, необходимо писать короткий проверочный код, в котором проявляется проблема и нет ничего лишнего. В Вашем случае это будет строк сорок - не больше.
Попробуйте написать такой код и погоняйте его. Почти наверняка вопрос снимется сам собой, а если нет, то любой (я, например) запустит его у себя, посмотрит, и, возможно, поможет.
Пока же у Вас код на 350+ строк, Вы и сами в нём не разберётесь и другой никто разбираться не полезет.
Попробуйте сделать как я сказал, увидите результат.
Хороший совет.
Между делом запускал такой код для проверки первым делом:
void setup() {
Serial.begin(115200);
}
void loop() {
if (Serial.available()) { // If anything comes in Serial (USB),
Serial1.write(Serial.read()); // read it and send it out Serial1 (pins 0 & 1)
}
}
он тоже не работает, те сигнализирует о том, что ничего не принимается.
Я сначала был уверен. что это программная проблема, каким-то образом, хотя все ок.
Но сейчас сижу паяю - адаптер с 3.3в на 5в. почему-то уверен, что баг аппаратный. Хотя пол огике должно работать…
спаял. не работает. через адаптер так же не видно запроса. странно.
какой-то полтергейст. мега (уже три штуки перепробовал) не видит входящих символов на уарте от одноплатника. пробовал через адаптер 5В-3.3В (адаптер проверил на свистке -все ок).
Может как-то надо уарт на меге дополнительно настраивать? Я уже хз что думать
Последовательная шина: 0 (RX) и 1 (TX); Последовательная шина 1: 19 (RX) и 18 (TX); Последовательная шина 2: 17 (RX) и 16 (TX); Последовательная шина 3: 15 (RX) и 14 (TX). Выводы используются для получения (RX) и передачи (TX) данных TTL. Выводы 0 и 1 подключены к соответствующим выводам микросхемы последовательной шины ATmega8U2.