Помогите с Serial для связи Mega и Nodemcu
- Войдите на сайт для отправки комментариев
Здравствуйте. Имеются две платы с контроллерами, один китайская Arduino Mega V3, другой Nodemcu V1. Нужно чтобы они умели обмениваться по Serial. Эти микроконтроллеры управляют системой из 3 шаговых двигателей. Проблем не понятных мне много. Пробовал запитывать движки и контроллеры от разных источников но не помогло.
1. Когда я директивой компилятора _OTLADKA_ включаю отладочные сообщения, микроконтроллеры хоть и с ошибками, но все же в состоянии управлять шаговыми двигателями. В противном случае движки стоят нешелохнувшись.
2. NodeMCU время от времени теряет соединение с сервером. Это очень мешает управлению приводами. Отсюда вопрос, это происходит у них на сервере или это мой обмен что-то там портит?
3. Постоянно читаю в обмене контроллерами по Serial какой-то мусор после сообщения, хотя скорость обмена всего 9600. Как от этого избавиться?
Код для arduino Mera:
#include <Stepper.h> #include <AccelStepper.h> #include <Math.h> #include <avr/interrupt.h> #define _OTLADKA_ //#define _UNO_ #define _ACCEL_ //#define _SX674_ // оптостопор #define INTERRUPT_PIN 19 // pin Rx для Serial1 #define MAX_READBYTES 99 // максимальная кол-во считываемых байт, // остальные игнорируются #define SERIAL_BAUDRATE 9600 // скорость обмена с Serial #define SERIAL_1_BAUDRATE 9600 // скорость обмена с Serial_1 const byte MAX_WaitingCount = 50; // макс кол-во циклов ожидания данных = мсек // Входящие команды const int Speed_AZ = 10; const int Speed_UM = 12; const int Speed_FC = 14; const int navSpeed = 22; const int trckSpdX = 30; //AZ const int trckSpdY = 32; //UM const int FocusPos = 20; //const int usr_speed_1 = 21; // Резервные команды const int var1 = 40; const int var2 = 41; const int var3 = 42; const int var4 = 43; const int var5 = 44; const int var6 = 45; // Исходящие команды //int FC_com_pos_out = 101; //int AZ_com_pos_out = 102; //int UM_com_pos_out = 103; //================ String data_string = ""; int step_del = 4; unsigned int time_delay_recording = 300; int DirPin = 26; int StepPin = 28; long long myTime = 0; long long myOldTime = 0; const int mk_step = 16; // 1/микрошаг драйвера. Если = 1 значит нет микрошага const int FC_mk_step = 16; // 1/микрошаг драйвера. Если = 1 значит нет микрошага const float FC_pitch = 8.0; // шаг винта (мм) const float pitch = 2.0; // шаг винта по осям (мм) const int step_per_turn = 200 * mk_step; // макс. количество полных (микро)шагов привода на оборот const float min_linear_step = pitch / step_per_turn; // линейное перемещение за один микрошаг //================================= Для расчета зависимости угла от шагов ======================== const int length_1 = 170; // длина первого плеча исходя из чертежа модели (мм) const float length_2 = 133.15; // длина второго плеча --//-- (мм) const float start_abs_angel_UM = 22; // начальный угол (исходя из чертежа модели) const float end_abs_angel_UM = 129.73333333333; // конечный угол (исходя из чертежа модели) const float horisontal_angel_UM = 36.73333333333; // горизонтальное положение телескопа (исходя из чертежа модели) float shpilka_length_UM; const float start_length_UM = sqrt(pow(length_1, 2) + pow(length_2, 2) - 2 * length_1 * length_2 * cos(start_abs_angel_UM * PI / 180)); // вычисленное удлинение шпильки для данного угла (мм) const float end_length_UM = sqrt(pow(length_1, 2) + pow(length_2, 2) - 2 * length_1 * length_2 * cos(end_abs_angel_UM * PI / 180)); // вычисленное удлинение шпильки для данного угла (мм) const float horisont_pos_length_UM = sqrt(pow(length_1, 2) + pow(length_2, 2) - 2 * length_1 * length_2 * cos(horisontal_angel_UM * PI / 180)); // вычисленное удлинение шпильки для данного угла (мм) const long start_abs_step_UM = start_length_UM / min_linear_step; // 109157; // Стартовый шаг винта УМ у упора (виртуальный от основания винта) const long end_abs_step_UM = end_length_UM / min_linear_step;//439830; const long start_step_UM = horisont_pos_length_UM / min_linear_step; // шаг горизонтального положение телескопа (виртуальный, от основания винта) //int mkstep_per_turn = step_per_turn * mk_step; //int length_3; unsigned long steps_count_UM = 0; //================================================================================================= // =================================Фокусер======================================================== float focus_position = 200; long steps_count_FC = 0; const long max_FC_length = 300; float FC_length = 0; //1 / FC_mk_step * step_per_turn * steps_count_FC; const long infinity = FC_mk_step * 200 * focus_position / FC_pitch; const long max_FC_steps = max_FC_length * FC_mk_step * 200 / FC_pitch; // =====================================АЗИМУТ===================================================== const unsigned int AZ_length_1 = 164; const unsigned int AZ_length_2 = 155; const float start_abs_angel_AZ = 18; const float end_abs_angel_AZ = 155; // конечный угол (исходя из чертежа модели) const float work_angel_AZ = 85; const float start_length_AZ = sqrt(pow(AZ_length_1, 2) + pow(AZ_length_2, 2) - 2 * AZ_length_1 * AZ_length_2 * cos(start_abs_angel_AZ * PI / 180)); // вычисленное удлинение шпильки для данного угла (мм) const float end_length_AZ = sqrt(pow(AZ_length_1, 2) + pow(AZ_length_2, 2) - 2 * AZ_length_1 * AZ_length_2 * cos(end_abs_angel_AZ * PI / 180)); // вычисленное удлинение шпильки для данного угла (мм) const float work_pos_length_AZ = sqrt(pow(AZ_length_1, 2) + pow(AZ_length_2, 2) - 2 * AZ_length_1 * AZ_length_2 * cos(work_angel_AZ * PI / 180)); // вычисленное удлинение шпильки для данного угла (мм) const float start_abs_step_AZ = start_length_AZ / min_linear_step; // 109157; // Стартовый шаг винта УМ у упора (виртуальный от основания винта) const long end_abs_step_AZ = end_length_AZ / min_linear_step;//439830; const long start_step_AZ = work_pos_length_AZ / min_linear_step; //const int start_abs_step_AZ = 81100; // Стартовый шаг винта AZ у упора (виртуальный от основания винта) //const int end_abs_step_AZ = 498400; // Стартовый шаг винта AZ у упора (виртуальный от основания винта) //int abs_angel_AZ; // относительные углы в треугольнике float abs_angle_AZ = 0.0; float abs_angle_UM = 0.0; unsigned long steps_count_AZ = 0; //================================================================================================= float abs_angle_AZ_grad = 0.0; float abs_angle_UM_grad = 0.0; float oldSpeed = 0; int all_ena = 0; unsigned char Slejenie = 0; // Автроподбор скорости слежения //const unsigned long Slejenie_time = 30; //const unsigned long Old_Slejenie_time = 30; const unsigned short mas_rec_length = 100; //const unsigned char rec_num_length = 30; long rec_mass_AZ[mas_rec_length]; long rec_mass_UM[mas_rec_length]; short i_mass = 1; long curr_speed; long long currTime = 0; const int stepsPerRevolution = 200 / step_del; // change this to fit the number of steps per revolution // for your motor // int Stopor = 0; // initialize the stepper library on pins 26 through 28: #ifdef _ACCEL_ AccelStepper AccelstepperFC(AccelStepper::FULL2WIRE, 26, 28); #endif // initialize the stepper library on pins 26 through 28: #ifdef _ACCEL_ AccelStepper AccelstepperAZ(AccelStepper::FULL2WIRE, 23, 25); #endif // initialize the stepper library on pins 26 through 28: #ifdef _ACCEL_ AccelStepper AccelstepperUM(AccelStepper::FULL2WIRE, 22, 24); #endif // initialize the stepper library on pins 26 through 28: //AccelStepper Accelstepper4(AccelStepper::FULL2WIRE, 27, 29); //Stepper myStepper4(stepsPerRevolution, 27, 29); #ifdef _ACCEL_ long FC_big_spd = 60 * mk_step; long FC_low_spd = 60 * mk_step / 8; long spd_AZ = 30; long spd_UM = 30; long acceleration = 500; long FC_acceleration = 300; #else long Speed_1 = 400 * step_del * 8; //= 960 мкШ/с = 60 Шг/с //long Speed_2 = 50 * step_del * 2; //= 30 мкШ/с int Speed1 = 400 * step_del; #endif long FocusPosition = 0; float trck_spd_x = 0; float trck_spd_y = 0; unsigned long last_time = 0; short wait_time = 1000; #ifdef _UNO_ int wait_counter = 1; #else int wait_counter1 = 0; int wait_counter2 = 0; #endif bool StpStpr1 = 0; bool StpStpr2 = 0; bool StpStpr3 = 0; bool StpStpr4 = 0; bool stop_ust = 0; // Выходы на управление приводами const unsigned char MCU_D3 = 6; // крутят вперед (1-ый привод фокусер) const unsigned char MCU_D4 = 5; // крутят назад const unsigned char MCU_D0 = 8; // меньше скорость const unsigned char MCU_D5 = 10; // Крутят назад (2-ой привод АЗ) const unsigned char MCU_D6 = 9; // крутят вперед const unsigned char MCU_D1 = 7; // крутят назад const unsigned char MCU_D2 = 11; // удержание //unsigned char MCU_RX = ; //unsigned char MCU_TX = ; // Входы с оптодатчиков const unsigned char SX674_1 = 39; const unsigned char SX674_2 = 37; const unsigned char SX674_3 = 38; const unsigned char SX674_4 = 36; // Выходы для отключения удержания unsigned char P1_ena = 2; unsigned char P2_ena = 3; unsigned char P3_ena = 4; // Массисы символов для протокола обмена char unitID_in[5]; char command_in[10]; char data_in[10]; char fake_in[39]; int ledpin = 13; int V20_on = 0; int V21_on = 0; // ===== SETUP ==== void setup() { // initialize the digital pin as an output. pinMode(ledpin, OUTPUT); #ifdef _UNO_ #else // Назначение режимов ножкам I\O pinMode(P1_ena, OUTPUT); pinMode(P2_ena, OUTPUT); pinMode(P3_ena, OUTPUT); pinMode(MCU_D3, INPUT); pinMode(MCU_D4, INPUT); // From NodeMCU pinMode(MCU_D0, INPUT); pinMode(MCU_D1, INPUT); pinMode(MCU_D2, INPUT); pinMode(MCU_D5, INPUT); pinMode(MCU_D6, INPUT); // pinMode(MCU_D7, INPUT); // pinMode(MCU_D8, INPUT); // Microstep pinMode(44, OUTPUT); pinMode(45, OUTPUT); pinMode(46, OUTPUT); pinMode(47, OUTPUT); pinMode(48, OUTPUT); pinMode(49, OUTPUT); digitalWrite(44, HIGH); // D2 digitalWrite(45, LOW); // D1 digitalWrite(46, HIGH); // D2 digitalWrite(47, LOW); // D1 digitalWrite(48, LOW); // D1 digitalWrite(49, HIGH ); // D2 // Стопор pinMode(SX674_1, INPUT); pinMode(SX674_2, INPUT); pinMode(SX674_3, INPUT); pinMode(SX674_4, INPUT); #endif // set the speed at 60 rpm: #ifdef _ACCEL_ AccelstepperFC.setMaxSpeed(FC_big_spd); AccelstepperFC.setAcceleration(FC_acceleration); AccelstepperAZ.setMaxSpeed(spd_AZ); AccelstepperAZ.setAcceleration(acceleration); AccelstepperUM.setMaxSpeed(spd_UM); AccelstepperUM.setAcceleration(acceleration); #endif // initialize the serial port: #ifdef _OTLADKA_ Serial.begin(SERIAL_BAUDRATE); #endif #ifndef _UNO_ Serial1.begin(SERIAL_1_BAUDRATE); #endif attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), f_Serial_1_ISR, RISING); // #ifdef _ACCEL_ //#ifdef _SX674_ adjustment(AccelstepperFC, AccelstepperAZ, AccelstepperUM); //#endif #endif #ifdef _OTLADKA_ #ifndef _UNO_ Serial.println("===================== УГОЛМЕСТА ====================:"); Serial.println(""); Serial.print("Линейное перемещение за один микрошаг: "); Serial.println(min_linear_step, 5); Serial.print("Расстояние от начала шпильки до гайки у упора УМ: "); Serial.println(start_length_UM); Serial.print("Расстояние до гайки в конце пути УМ: "); Serial.println(end_length_UM); Serial.print("Горизонтальное положение : "); Serial.println(horisont_pos_length_UM); Serial.print("Положение старотового шага УМ: "); Serial.println(start_abs_step_UM); Serial.print("Положение конечного шага УМ: "); Serial.println(end_abs_step_UM); Serial.print("Шаг в горизонтальном положении трубы по УМ: "); Serial.println(start_step_UM); delay(1000); Serial.println(""); Serial.println("===================== АЗИМУТ ====================:"); Serial.println(""); Serial.print("Линейное перемещение за один микрошаг: "); Serial.println(min_linear_step, 5); Serial.print("Расстояние от начала шпильки до гайки у упора AZ: "); Serial.println(start_length_AZ); Serial.print("Расстояние до гайки в конце пути AZ: "); Serial.println(end_length_AZ); Serial.print("Среднее положение: "); Serial.println(work_pos_length_AZ); Serial.print("Положение старотового шага AZ: "); Serial.println(start_abs_step_AZ); Serial.print("Положение конечного шага AZ: "); Serial.println(end_abs_step_AZ); Serial.print("Среднее положение в шагах АЗ: "); Serial.println(start_step_AZ); delay(1000); Serial.println(""); Serial.println("===================== ФОКУСЕР ====================:"); Serial.println(""); Serial.print("Бесконечность: "); Serial.println(infinity); Serial.print("Max steps: "); Serial.println(max_FC_steps); Serial.println(""); // Serial.print(""); // Serial.println(); // delay(5000); #endif #endif delay(1000); } //-------------------------------------------------------------------------------- String Serial1_string; // результат чтения(строка) byte Serail1_byte[MAX_READBYTES]; // результат чтения(байт) int WaitingCount = 0; // время ожидания данных, мс int Serial_amount = 0; // кол-во прочитанных байт volatile boolean flag_Serial_1 = false; // флаг чтения данных //========================================= LOOP ============== void loop() { if (flag_Serial_1) // установлен флаг прерывания { f_Serial_1_Handler(); // чтение данных из Serial1 if (Serial_amount) // имеются прочитанные данные { f_testoutput(); // тестовый вывод результата чтения или обработка полученных данных f_ReadingEnd(); // ОБЯЗАТЕЛЬНО !!! подготовка к чтению следующего пакета } } f_ReadingEnd(); steps_count_AZ = AccelstepperAZ.currentPosition(); steps_count_UM = AccelstepperUM.currentPosition(); // Перевод углов в градусы abs_angle_AZ = acos((pow(AZ_length_1, 2) + pow(AZ_length_2, 2) - pow(((steps_count_AZ * pitch) / (step_per_turn)), 2)) / (2 * AZ_length_1 * AZ_length_2)); abs_angle_UM = acos((pow(length_1, 2) + pow(length_2, 2) - pow(((steps_count_UM * pitch) / (step_per_turn)), 2)) / (2 * length_1 * length_2)); abs_angle_AZ_grad = abs_angle_AZ * 180 / PI; abs_angle_UM_grad = abs_angle_UM * 180 / PI; // Скорости в сек/10/сек. Для задания умножить на множитель // float speed_x = (40672000 * sin(abs_angle_AZ) / sqrt(50921 - 50840 * cos(abs_angle_AZ))) * (PI / 180) / 36000; // float speed_y = (724336000 * sin(abs_angle_UM) / sqrt(18651569 - 18108400 * cos(abs_angle_UM))) * (PI / 180) / 36000; #ifdef _OTLADKA_ /* Serial.print("AZ_length_1: "); Serial.println(AZ_length_1); Serial.print("AZ_length_2: "); Serial.println(AZ_length_2); Serial.print("steps_count_AZ: "); Serial.println(steps_count_AZ); Serial.print("pitch: "); Serial.println(pitch); Serial.print("step_per_turn: "); Serial.println(step_per_turn); Serial.print("По Х (азимут): "); Serial.println(speed_x, 9); Serial.print("По Y (угол места): "); Serial.println(speed_y, 9); Serial.print("УГОЛ АЗ: "); Serial.println(abs_angle_AZ); Serial.print("УГОЛ УМ: "); Serial.println(abs_angle_UM); */ #endif delay(10); // ======== Отслеживание режима увеличенной скорости ============= // Управление удержанием if (digitalRead(MCU_D2)) { all_ena = 1; digitalWrite(P1_ena, LOW); digitalWrite(P2_ena, LOW); digitalWrite(P3_ena, LOW); } else { all_ena = 0; digitalWrite(P1_ena, HIGH); digitalWrite(P2_ena, HIGH); digitalWrite(P3_ena, HIGH); } delay(20); #ifndef _ACCEL_ // Команды на вращение по и против часовой стрелке // для первого двигателя RotateForward(myStepper1, MCU_D3, P1_ena); RotateBackward(myStepper1, MCU_D4, P1_ena); #else // _ACCEL_ // Команды на вращение по и против часовой стрелке // для фокусера RotateForward(AccelstepperFC, MCU_D3, P1_ena); RotateBackward(AccelstepperFC, MCU_D4, P1_ena); if (Slejenie == 1) { tracking(AccelstepperFC, AccelstepperAZ, AccelstepperUM ); } // для азимутальных и угломестных двигателей RotateForward(AccelstepperAZ, MCU_D5, P2_ena); RotateBackward(AccelstepperAZ, MCU_D6, P2_ena); // для третьего двигателся RotateForward(AccelstepperUM, MCU_D0, P3_ena); RotateBackward(AccelstepperUM, MCU_D1, P3_ena); // RotateForward(myStepper4, MCU_D7, StpStpr4); // RotateBackward(myStepper4, MCU_D8, SX674_4, StpStpr4); #endif //ifdef _ACCEL_ #ifdef _ACCEL_ // Отправляем положение в программу на смартфоне data_string += String("567,101,"); data_string += String(AccelstepperFC.currentPosition() / 2); data_string += String(",1"); Serial1.println(data_string); #ifdef _OTLADKA_ Serial.println(data_string); #endif delay(40); data_string = ""; // то же для АЗ и УМ data_string += String("567,102,"); data_string += String((abs_angle_AZ_grad) * 100); // 36 , 18 data_string += String(",1"); Serial1.println(data_string); #ifdef _OTLADKA_ Serial.println(data_string); #endif delay(40); data_string = ""; data_string += String("567,103,"); data_string += String((abs_angle_UM_grad) * 100); //50 , 36.73 data_string += String(",1"); Serial1.println(data_string); #ifdef _OTLADKA_ Serial.println(data_string); #endif delay(40); data_string = ""; // TuneSpeed(AccelstepperAZ, AccelstepperUM); #endif } // ===== LOOOOOOOOP ======================== bool RotateForward(AccelStepper &myStepper, unsigned char rotating, int ena) { long Stopor = 0; switch (rotating) { case MCU_D3 : case MCU_D4 : Stopor = max_FC_steps; break; case MCU_D5 : case MCU_D6 : Stopor = start_abs_step_AZ; break; case MCU_D0 : case MCU_D1 : Stopor = end_abs_step_UM; break; } myStepper.moveTo(Stopor); #ifdef _OTLADKA_ Serial.print("Moving FORWARD to stopor: "); Serial.println(Stopor); Serial.println("Current position: "); Serial.println(myStepper.currentPosition()); #endif if (digitalRead(rotating)) { digitalWrite(ena, LOW); // включить драйвер delay(2); while (digitalRead(rotating)) { // myStepper.maxSpeed(); myStepper.run(); if (flag_Serial_1) // установлен флаг прерывания { f_Serial_1_Handler(); // чтение данных из Serial1 if (Serial_amount) // имеются прочитанные данные { #ifdef _OTLADKA_ f_testoutput(); // тестовый вывод результата чтения или обработка полученных данных #endif f_ReadingEnd(); // ОБЯЗАТЕЛЬНО !!! подготовка к чтению следующего пакета } } } oldSpeed = myStepper.speed(); myStepper.setMaxSpeed(0); while (myStepper.speed() != 0) { myStepper.run(); } myStepper.setMaxSpeed(oldSpeed); } // myStepper.stop(); return 1; } bool RotateBackward(AccelStepper &myStepper, unsigned char rotating, int ena) { long Stopor = 0; switch (rotating) { case MCU_D3 : case MCU_D4 : Stopor = 0; break; case MCU_D5 : case MCU_D6 : Stopor = end_abs_step_AZ; break; case MCU_D0 : case MCU_D1 : Stopor = start_abs_step_UM; break; } myStepper.moveTo(Stopor); #ifdef _OTLADKA_ Serial.print("Moving BACKWARD to stopor: "); Serial.println(Stopor); Serial.print("Current position: "); Serial.println(myStepper.currentPosition()); Serial.print("Speed: "); Serial.println(myStepper.speed()); #endif if (digitalRead(rotating)) { digitalWrite(ena, LOW); // включить драйвер delay(2); while (digitalRead(rotating)) // Крутят назад { myStepper.run(); if (flag_Serial_1) // установлен флаг прерывания { f_Serial_1_Handler(); // чтение данных из Serial1 if (Serial_amount) // имеются прочитанные данные { #ifdef _OTLADKA_ f_testoutput(); // тестовый вывод результата чтения или обработка полученных данных #endif f_ReadingEnd(); // ОБЯЗАТЕЛЬНО !!! подготовка к чтению следующего пакета } } } oldSpeed = myStepper.speed(); myStepper.setMaxSpeed(0); while (myStepper.speed() != 0) { myStepper.run(); } myStepper.setMaxSpeed(oldSpeed); } // myStepper.stop(); return 1; } //Функция поиска нулей /* Описание Только при включении должна выполняться эта функция, и задаются позиции упоров. Далее эти упоры не используются */ // =================== ЮСТИРОВКА ================= void adjustment(AccelStepper &FC, AccelStepper &AZ, AccelStepper &UM) { #ifdef _OTLADKA_ Serial.println("Юстировка приводов"); #endif // delay(500); // установка скорости #ifdef _SX674_ FC.setSpeed(mk_step * step_per_turn * 2); FC.moveTo(-10000000); UM.setSpeed(mk_step * step_per_turn * 4); AZ.setSpeed(mk_step * step_per_turn * 4); UM.moveTo(-10000000); AZ.moveTo(-10000000); stop_ust = 0; int ust_off = 0; int stop_ust_FC = 0; while (!stop_ust_FC) { int wait_counter0 = 0; last_time = millis(); while (((millis() - last_time ) < wait_time)) { FC.runSpeed(); wait_counter0 += digitalRead(SX674_1); } if (wait_counter1 == 0) { stop_ust_FC = 1; FC.setCurrentPosition(0); } } while (!stop_ust) { wait_counter1 = 0; wait_counter2 = 0; last_time = millis(); while (((millis() - last_time ) < wait_time)) { if (ust_off != 1) { AZ.runSpeed(); wait_counter1 += digitalRead(SX674_2); // } if (ust_off != 2) { UM.runSpeed(); wait_counter2 += digitalRead(SX674_3); // } } if (wait_counter1 == 0) { ust_off = 1; AZ.setCurrentPosition(start_abs_step_AZ); } if (wait_counter2 == 0) { if (wait_counter1 == 0) stop_ust = 1; ust_off = 2; UM.setCurrentPosition(start_abs_step_UM); } } #else UM.setCurrentPosition(109157); // -22 AZ.setCurrentPosition(158316); // - 36 FC.setCurrentPosition(400); UM.setMaxSpeed(100); AZ.setMaxSpeed(100); FC.setMaxSpeed(0); #endif // AccelstepperUM.moveTo(166473); // AccelstepperAZ.moveTo(344985); // AccelstepperFC.moveTo(infinity); // AccelstepperUM.runToPosition(); // AccelstepperAZ.runToPosition(); // AccelstepperFC.runToPosition(); } void tracking(AccelStepper &FC, AccelStepper &AZ, AccelStepper &UM ) { long Stopor1 = max_FC_steps; long Stopor2 = start_abs_step_AZ; long Stopor3 = end_abs_step_UM; // FC.moveTo(Stopor1); FC.moveTo(Stopor1); AZ.moveTo(Stopor2); UM.moveTo(Stopor3); AccelstepperFC.setMaxSpeed(0); digitalWrite(P1_ena, LOW); digitalWrite(P2_ena, LOW); digitalWrite(P3_ena, LOW); while (Slejenie) { FC.run(); AZ.run(); UM.run(); if (flag_Serial_1) // установлен флаг прерывания { f_Serial_1_Handler(); // чтение данных из Serial1 if (Serial_amount) // имеются прочитанные данные { #ifdef _OTLADKA_ f_testoutput(); // тестовый вывод результата чтения или обработка полученных данных #endif f_ReadingEnd(); // ОБЯЗАТЕЛЬНО !!! подготовка к чтению следующего пакета } } if (digitalRead(MCU_D4)) FC.moveTo(0); if (digitalRead(MCU_D3)) FC.moveTo(Stopor1); if (V20_on) UM.moveTo(end_abs_step_UM); else UM.moveTo(start_abs_step_UM); if (V21_on) AZ.moveTo(end_abs_step_AZ); else AZ.moveTo(start_abs_step_AZ); if (FocusPosition == 0) digitalWrite(P1_ena, HIGH); else digitalWrite(P1_ena, LOW); } } void f_Serial_1_ISR() { if (!flag_Serial_1) flag_Serial_1 = true; } //========================================================================= void f_Serial_1_Handler() { #ifdef _OTLADKA_ Serial.println("======= INT_HANDLE ======"); #endif if (Serial_amount) return; detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN)); Serial1_string = ""; WaitingCount = 0; while (!Serial1.available() and (WaitingCount < MAX_WaitingCount)) { WaitingCount++; delay(1); } delay(10); char tmp_buffer[100]; while (Serial1.available() && (Serial_amount < MAX_READBYTES)) { delay(1); char inChar = (char)Serial1.read(); tmp_buffer[Serial_amount++] = inChar; sscanf(tmp_buffer, "%[^','],%[^','],%[^','],%s", &unitID_in, &command_in, &data_in, &fake_in); } #ifdef _OTLADKA_ Serial.println("=========\\ ПРИНЯТО С ПОРТА //==========="); Serial.println(String(tmp_buffer)); // delay(100); #endif switch (atoi(command_in)) { case navSpeed : switch (atoi(data_in)) { case 1: // Speed2 = Speed_2 / 2; Slejenie = 1; break; case 2: // Speed2 = Speed_2 * 2; spd_AZ = 30 * 2; spd_UM = 30 * 2; AccelstepperAZ.setMaxSpeed(spd_AZ); AccelstepperUM.setMaxSpeed(spd_UM); Slejenie = 0; break; case 3: spd_AZ = 180; spd_UM = 180; AccelstepperAZ.setMaxSpeed(spd_AZ); AccelstepperUM.setMaxSpeed(spd_UM); // Speed2 = Speed_1; Slejenie = 0; break; case 4: spd_AZ = 3000; spd_UM = 3000; AccelstepperAZ.setMaxSpeed(spd_AZ); AccelstepperUM.setMaxSpeed(spd_UM); Slejenie = 0; break; default: Slejenie = 0; } break; case FocusPos : FocusPosition = atoi(data_in); // AccelstepperFC.setMaxSpeed(1000); AccelstepperFC.setMaxSpeed(FocusPosition * 100); break; case trckSpdX : trck_spd_x = atoi(data_in); // AccelstepperAZ.setMaxSpeed(1000); AccelstepperAZ.setMaxSpeed(trck_spd_x); // myStepper2.setSpeed(trck_spd_x / 13.333333333333); break; case trckSpdY : trck_spd_y = atoi(data_in); // AccelstepperUM.setMaxSpeed(1000); AccelstepperUM.setMaxSpeed(trck_spd_y); // myStepper3.setSpeed(trck_spd_y / 13.333333333333); break; case 50: V20_on = atoi(data_in); break; case 51: V21_on = atoi(data_in); break; default: #ifdef _OTLADKA_ Serial.println("Error... Reseting Serial1."); #endif while (Serial1.available() > 0) // очистка остатка данных в Serial_1 { int cii = Serial1.read(); } Serial1.end(); delay(20); Serial1.begin(SERIAL_1_BAUDRATE); } attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), f_Serial_1_ISR, RISING); } void f_testoutput() { #ifdef _OTLADKA_ Serial.print("unitID_in: "); Serial.print(unitID_in); Serial.println(", "); Serial.print("command_in^ "); Serial.print(command_in); Serial.println(", "); Serial.print("data_in: "); Serial.print(data_in); Serial.println("; "); #else // delay(1); #endif } // end of f_testoutput() //-------------------------------------------------------------------------------- // подготовка к чтению следующего пакета void f_ReadingEnd() { // Serial.println(" ===== f_ReadingEnd ========= "); while (Serial1.available() > 0) // очистка остатка данных в Serial_1 { int cii = Serial1.read(); } // !!!!! ОБЯЗАТЕЛЬНО СНЯТЬ ФЛАГ для чтение следующего пакета flag_Serial_1 = false; // снимаем флаг для ISR Serial_amount = 0; WaitingCount = 0; }// end of f_ReadingEnd()
Код для NodeMCU
/************************************************************* Download latest Blynk library here: https://github.com/blynkkk/blynk-library/releases/latest Blynk is a platform with iOS and Android apps to control Arduino, Raspberry Pi and the likes over the Internet. You can easily build graphic interfaces for all your projects by simply dragging and dropping widgets. Downloads, docs, tutorials: http://www.blynk.cc Sketch generator: http://examples.blynk.cc Blynk community: http://community.blynk.cc Follow us: http://www.fb.com/blynkapp http://twitter.com/blynk_app Blynk library is licensed under MIT license This example code is in public domain. ************************************************************* This example runs directly on ESP8266 chip. Note: This requires ESP8266 support package: https://github.com/esp8266/Arduino Please be sure to select the right ESP8266 module in the Tools -> Board menu! Change WiFi ssid, pass, and Blynk auth token to run :) Feel free to apply it to any other example. It's simple! *************************************************************/ /* Comment this out to disable prints and save space */ #define BLYNK_PRINT Serial #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> //#include <stdio.h> BlynkTimer timer; //#define _OTLADKA_ #ifdef _OTLADKA_ #include <SoftwareSerial.h> SoftwareSerial mySerial(13, 15); #endif // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "9f78b922efbe4fee9fd69fee51ce8fbd"; // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "Xperia C_5bd0"; char pass[] = "12345678"; bool mega_reset = 0; //int app_speed = 0; String dataString = ""; unsigned long ui_command_in = 0; float ui_data_in = 0; char unitID_in[10]; char command_in[12]; char data_in[12]; char fake_in[39]; int FC_pos = 101; int AZ_pos = 102; int UM_pos = 103; int Var1 = 104; int Var2 = 105; int Var3 = 106; int Var4 = 107; int Var5 = 108; int Var6 = 109; int D0_read = 120; int D5_read = 121; long FC_steps = -1; float AZ_angel = -2; float UM_angle = -3; bool bPressD0 = 0; bool bPressD5 = 0; //unsigned short outArray[100]; void setup() { digitalWrite(13, HIGH); // Debug console Serial.begin(9600); #ifdef _OTLADKA_ mySerial.begin(9600); #endif Blynk.begin(auth, ssid, pass); timer.setInterval(3000, myFunc); // pinMode(16, OUTPUT); // pinMode(14, OUTPUT); } BLYNK_WRITE(V0) // пользовательское положение фокусера { int Focus_pos = param.asInt(); dataString += String("1,20,"); dataString += String(Focus_pos); dataString += String(",1"); Serial.println(dataString); dataString = ""; } BLYNK_WRITE(V1) { int usr_speed; char *buff; char spd[6]; switch (param.asInt()) { case 1: { Serial.println("o5k,00000022,00000001,1"); #ifdef _OTLADKA_ mySerial.println("o5k,00000022,00000001,1"); #endif break; } case 2: { Serial.println("o5k,0000022,00000002,1"); #ifdef _OTLADKA_ mySerial.println("o5k,0000022,00000002,1"); #endif break; } case 3: { Serial.println("o5k,00000022,00000003,1"); #ifdef _OTLADKA_ mySerial.println("o5k,00000022,00000003,1"); #endif break; } case 4: { Serial.println("o5k,00000022,00000004,1"); #ifdef _OTLADKA_ mySerial.println("o5k,00000022,00000004,1"); #endif break; } } } BLYNK_WRITE(V2) // пользовательская скорость AZ { int app_speed = param.asInt(); dataString += String("o5k,30,"); dataString += String(app_speed); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V6) // пользовательская скорость УМ { int app_speed1 = param.asInt(); dataString += String("o5k,32,"); dataString += String(app_speed1); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } // =================== Запаска ==================== BLYNK_WRITE(V7) // пользовательская скорость { float var1 = param.asInt(); dataString += String("o5k,00000040,"); dataString += String(var1); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V8) // пользовательская скорость { float var2 = param.asInt(); dataString += String("o5k,00000041,"); dataString += String(var2); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V9) // пользовательская скорость { float var3 = param.asInt(); dataString += String("o5k,00000042,"); dataString += String(var3); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V10) // пользовательская скорость { int var4 = param.asInt(); dataString += String("o5k,00000043,"); dataString += String(var4); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V11) // пользовательская скорость { int var5 = param.asInt(); dataString += String("o5k,00000044,"); dataString += String(var5); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V12) // пользовательская скорость { int var6 = param.asInt(); dataString += String("o5k,00000045,"); dataString += String(var6); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V20) // D0 { bPressD0 = param.asInt(); digitalWrite(16, bPressD0); dataString += String("o5k,00000050,"); dataString += String(bPressD0); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_WRITE(V21) // D5 { bPressD5 = param.asInt(); digitalWrite(14, bPressD5); dataString += String("o5k,00000051,"); dataString += String(bPressD5); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } BLYNK_READ(V3) { //Виртуальный пин V3 получает на смартфон количество прошедших микрошагов фокусера Blynk.virtualWrite(V3, FC_steps); } BLYNK_READ(V4) { //Виртуальный пин V3 получает на смартфон количество прошедших микрошагов АЗ Blynk.virtualWrite(V4, String(AZ_angel)); } BLYNK_READ(V5) { //Виртуальный пин V3 получает на смартфон количество прошедших микрошагов УМ Blynk.virtualWrite(V5, String(UM_angle)); } void loop() { if ((millis() > 2000) && (mega_reset == 0)) { digitalWrite(13, LOW); mega_reset = 1; delay(100); digitalWrite(13, HIGH); } /* if (digitalRead(16)) //D0 { delay(20); dataString += String("o5k,00000050,"); dataString += String("1"); dataString += String(",1"); Serial.println(dataString); #ifdef _OTLADKA_ mySerial.println(dataString); #endif dataString = ""; } if (digitalRead(14)) //D5 { } */ unsigned short outArray[24]; int i = 0; char tmp_buffer[100]; char *buffer1; String outTestStr = ""; if (Serial.available()) { delay(1); // while (!Serial.available()) delay(20); while (Serial.available() && i < 39) { delay(1); // пауза для принятия новой порции сообщения tmp_buffer[i++] = Serial.read(); } // tmp_buffer[i] = '\0'; char *p; byte t = 0; // sscanf(tmp_buffer, "%[^','],%[^','],%[^','],%s", &unitID_in, &command_in, &data_in, &fake_in); for ( buffer1 = strtok_r(tmp_buffer, ",", &p); buffer1; buffer1 = strtok_r(NULL, ",", &p)) { delay(1); outArray[t] = atoi(buffer1); switch (t % 3) { case 0: outTestStr += String(outArray[t]); outTestStr += String(", "); break; case 1: ui_command_in = outArray[t]; outTestStr += String(ui_command_in); outTestStr += String(", "); break; case 2: ui_data_in = outArray[t]; outTestStr += String(ui_data_in); outTestStr += String(", "); break; case 3: outTestStr += String(outArray[t]); break; } #ifdef _OTLADKA_ mySerial.print(outTestStr); #endif outTestStr = ""; t++; } #ifdef _OTLADKA_ mySerial.println(""); #endif i = 0; // ========= Распознавание команд и извлечение данных =============== if (ui_command_in == FC_pos) { FC_steps = ui_data_in; } if (ui_command_in == AZ_pos) { AZ_angel = ui_data_in / 100.0; } if (ui_command_in == UM_pos) { UM_angle = ui_data_in / 100.0; } }//if (Serial.available()) Blynk.run(); timer.run(); } void myFunc() { }
пипец :) Опять новичок, которые не знает, как по сериалу коннектится - но сразу хватается за код из 1000 строк...
ТС, вы хотя бы учитываете. что у ваших плат разные логические уровни? У Меги 5в, у НодеМКУ - 3.3. Их вообще нельзя соединять напрямую, надо через конверторы, а то порт на ESP-ке может погореть.
Может он у вас уже подгорел, что обьяснило бы глюки.
:) Прологические уровни в курсе, с самого начала конвертером пользовался. Я только подключил DO nodemcu к DI mega, но это мне кажется допустимо.
Забыл написать что пользуюсь серверами Blynk. Вроде нашел тему как бороться с зависонами сервера. Проверить не смог, сервера для прошивки esp опять упали.
Меня еще беспокоит почему при загрузке зависает намертво мега, когда подключен по serial к nodemcu. Приходится через пару секунд подтягивать reset к земле.
А мошт проще к автору карикатуры (скетча) обратиться?
Автор я, часть скетча позаимствовал из интернета, кое что пришлось самому писать. Ладно, я вас понял, буду сам разбираться.
Не отвечу на вопросы, так, замечания по скетчу:
1) "delay(1);": зачем (в каждом случае)? Коментарий в коде читал, но не понял, зачем нужная эта задержка перед чтением из порта.
2) Строки 875-877: зачем закрывать, а потом после ожидания - открывать порт?
Я не пробовал вникнуть в логику вашего скетча, возможно есть какая-то магия/специфика, но вот эти действия сразу в глаза бросились, и кажутся лишними и даже вредными.
В принципе я уже понял в чем была основная проблема - выход за пределы массива, когда приходит больше байт чем ожидаешь.
По поводу вопросов:
1) Скорость обмена у меня небольшая (около 1мс на символ) и я западозрил что могут быть ситуации когда я могу прочесть не все сообщение, а только его часть т.к. к моменту чтения буфера тупо не все успело прийти.
2) Это я на скорую руку решил таким образом сделать reset порта. Были подозрения что что-то не так с обменом. А эти зависания очень сильно портили работу системы.
1) Скорость обмена у меня небольшая (около 1мс на символ) и я западозрил что могут быть ситуации когда я могу прочесть не все сообщение, а только его часть т.к. к моменту чтения буфера тупо не все успело прийти.
2) Это я на скорую руку решил таким образом сделать reset порта. Были подозрения что что-то не так с обменом. А эти зависания очень сильно портили работу системы.
1) Из-за этой задержки потенциально может случиться, что буфер приёма (из него и отдаёт вам данные Serial.read()) переполнился и в него не попала часть данных при приёме. Наполняет буфер библиотека работы с последовательным портом. Ваша задача - как можно скорее прочитать данные из этого буфера.
2) Это наоборот, может только всё портить. Если есть проблема с неисправным портом - его надо менять, аппаратно. Если есть помехи, то сброс порта - не та мера; нужно избавиться от помех.
1) Не критично в моем случае.
2) Порт рабочий. Но аппаратные ошибки бывает можно программно обходить.
Я глубоко с микроконтроллерами не знаком, датащиты не читаю обычно. Для меня главное быстро написать и чтобы все работало. Времени вникать нет особо.
Я глубоко с микроконтроллерами не знаком, датащиты не читаю обычно. Для меня главное быстро написать и чтобы все работало. Времени вникать нет особо.
Если не вникать, то либо быстро, либо работает.
И еще - после таких заявлений пропадает всякое желание отвечать таким как вы. Думается - если самому человеку "нет времени вникать" в свою собственную задачу - то кто я, Мать Тереза что ли? - тратить свое время и вникать в чужие проблемы?
Есть люди с опытом и знаниями, которым найти ошибку не сложно. Это ж вам не чистый C++ а какая-то ардуинка. А задача мною решаемая - это вклад в мировую науку, причем все можно сказать за свой счет. Поэтому все максимально бюджетно.
А задача мною решаемая - это вклад в мировую науку, причем все можно сказать за свой счет. Поэтому все максимально бюджетно.
и вы хотите это решить за чей-то чужой счет ?
ну дак пока он "будет вникать", мировая наука будет простаивать же.
А задача мною решаемая - это вклад в мировую науку, причем все можно сказать за свой счет. Поэтому все максимально бюджетно.
и вы хотите это решить за чей-то чужой счет ?
Да, искал простачков, но видимо тут все крепкие орешки. Ладно 100000$ устроит?
В какую хотя бы науку вклад - можно узнать?
1) Из-за этой задержки потенциально может случиться, что буфер приёма (из него и отдаёт вам данные Serial.read()) переполнился и в него не попала часть данных при приёме. Наполняет буфер библиотека работы с последовательным портом. Ваша задача - как можно скорее прочитать данные из этого буфера.
Щас проверил. Любопытно, что Мега без этой задержки свободно читает порт без ошибок, а NodeMCU без нее порт читает с ошибками, вместо числа приходит ноль. Вот вам и разница.
В какую хотя бы науку вклад - можно узнать?
Астраляюбию :)
А мне подумалось -Акмеология )))
Я так понял это система дистанционного управления телескопом? Есть такой частный телескоп, под Кисловодском, отличные снимки делает, в том месте где установлен минимальная засветка ночного неба
Результат:
start_pos_AZ: 242364
start_pos_UM: 156898
end_pos_AZ: 218685
end_pos_UM: 154697
speed_time_counter: 273
curr_speed_AZ: 15731613
curr_speed_UM: 15732400
Почему результат деления целых чисел в unsigned и еще 24 битный? Раньше не сталкивался с таким.
В общем да.
Почему результат деления целых чисел в unsigned и еще 24 битный? Раньше не сталкивался с таким.
А какой должен быть результат деления целого на целое, помещенный в целое?
В данном случае отрицательный 32 битный
У меня всё ОК:
У вас работает по тому что speed_time counter имеет тип лонг, а у меня был оказывается беззнаковый. Ну и надо писать 10L вместо 10. В общем это видимо новый стандарт Си меня так сбивает. Раньше я пользовался каким то от 91 года.