проблема с меандрой
- Войдите на сайт для отправки комментариев
Пнд, 07/05/2018 - 22:51
Суть: Крутится шаговый двигатель и в момент считывания температуры (я так думаю), происходят проблемы с генерацией меандры. слышу кратковременный щелчек шагового. я точно знаю что возникает проблема с меандрой для шд и он кратковременно останавливается.
Не смог понять почему так происходит и сделал другую схему- https://yadi.sk/i/Pn2MqYM63VVmDr так все работает, но все таки прошу помочь разобраться в проблеме и обойтись одной ардуиной.
Ниже код первой ардуинки - подскажите где и что поправить - возможные источники проблем с меандрой.
extern int __bss_end; extern void *__brkval; // Функция, возвращающая количество свободного ОЗУ (RAM) int memoryFree() { int freeValue; if((int)__brkval == 0) freeValue = ((int)&freeValue) - ((int)&__bss_end); else freeValue = ((int)&freeValue) - ((int)__brkval); return freeValue; } #include <EEPROM.h> #include <SoftwareSerial.h> SoftwareSerial MotorSerial(2,3); // RX, TX String HC12Buff; #include <OneWire.h> #include <DallasTemperature.h> OneWire oneWire(4); DallasTemperature tempMotor(&oneWire); float tempMotorRound; #include "max6675.h" MAX6675 temp1(9, 8, 7 ); float tempRound1; #include <PID_v1.h> double Setpoint, Input, Output; double Kp=1, Ki=1, Kd=1; PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE); //REVERSE double Kpow; //выходная мощность Output int PIDStatus=0; unsigned long PIDstart=0; int BadStatus=0; int TempMotorMax=60; int TempPIDMax=350; int TempPIDMin=180; long Mspeed=0, MspeedMax=0; unsigned long t1; int WindowSize = 5000; unsigned long windowStartTime; void setup() { // put your setup code here, to run once: Serial.begin(9600); MotorSerial.begin(9600); tempMotor.begin(); EEPROM.get(0, Setpoint); if ((Setpoint<40) or (Setpoint>350)) {Setpoint=200;} EEPROM.get(10, Kp); if ((Kp<0) or (Kp>999)) {Kp=1;} EEPROM.get(20, Ki); if ((Ki<0) or (Ki>999)) {Ki=1;} EEPROM.get(30, Kd); if ((Kd<0) or (Kd>999)) {Kd=1;} EEPROM.get(40, Kpow); if ((Kpow<0) or (Kpow>5000)) {Kpow=5000;} EEPROM.get(50, MspeedMax); if ((MspeedMax<0) or (MspeedMax>100000)) {MspeedMax=10000;} EEPROM.get(60, TempMotorMax); if ((TempMotorMax<0) or (TempMotorMax>999)) {TempMotorMax=60;} EEPROM.get(70, TempPIDMax); if ((TempPIDMax<0) or (TempPIDMax>999)) {TempPIDMax=350;} EEPROM.get(80, TempPIDMin); if ((TempPIDMin<0) or (TempPIDMin>999)) {TempPIDMin=180;} Mspeed=0; tempRound1=temp1.readCelsius(); PIDstart=0; //для нижнего предела таймер в 20 минут pinMode(5,OUTPUT); //АО БП ШД, нагревателей pinMode(6,OUTPUT); //Нагреватель SSR t1=0; windowStartTime = millis(); //Первая рабочая //Kp=100; //Ki=1; //Kd=1; //PIDBegin_200_200_1_50_PIDEnd_ ///Задано в пид регуляторе //Kp=30; //Ki=240; //Kd=60; //'PIDBegin_200_30_240_60_PIDEnd_' } void loop() { // put your main code here, to run repeatedly: //Serial.println(memoryFree()); if (tempMotorRound>=TempMotorMax) {BadStatus=1;} //если температура мотора превышает указанный параметр тогда аварийный останов if (tempRound1>=TempPIDMax) {BadStatus=1;} //если температура нагревателя превышает указанный параметр тогда аварийный останов if (PIDStatus==1) { if ( (PIDstart+20*60000)<millis() ) { //если прошло 20 минут с момента начала нагрева, //то ВЕРОЯТНО нагреватель прогрелся как следует и прошел порог минимального нагрева if (tempRound1<=TempPIDMin) {BadStatus=1;} //если температура нагревателя меньше указанного параметра тогда аварийный останов } } if ((PIDStatus==1) or (Mspeed>0)) { if (BadStatus==1) { digitalWrite(5,0); while (true) {Serial.print(">_BAD_<"); delay(1000);} } else { digitalWrite(5,1);} } //АО БП ШД, нагревателей //выключаем БП двигателя и нагревателей, посылаем бесконечно аварию //Если включен нагрев или включен мотор шнека то включаем аварию. т.к. в других случаях нет возможности понять что случилось в плате if (PIDStatus==0) { digitalWrite(6,0); PIDstart=0; } //Нагреватель SSR //Работа PID нагревателя если его активировали if (PIDStatus==1) { if (PIDstart==0) {PIDstart=millis();} //фиксируем время первого начала нагрева Input = tempRound1; myPID.Compute(); //Serial.print(Input); //Serial.print(" "); //Serial.println(Output); if (millis() - windowStartTime > WindowSize) { //time to shift the Relay Window windowStartTime += WindowSize; } if (Output < millis() - windowStartTime) { digitalWrite(6, HIGH); } else {digitalWrite(6, LOW); } } //Работа PID нагревателя если его активировали ////////////////////////////////////// /////Прием от HC12 с протяжки if (Serial.available()) { while(Serial.available()) { while(Serial.available()) { char c = Serial.read(); HC12Buff+=c; } delay(10); } //'MspeedBegin_10000_MspeedEnd_' if ( (HC12Buff.indexOf("MspeedBegin")==0) and (HC12Buff.indexOf("MspeedEnd")>0) ) { char charVar[HC12Buff.length()+1]; HC12Buff.toCharArray(charVar, sizeof(charVar)); char *sInput =(char *)charVar; int h1=0; for (char *p = strtok(sInput, "MspeedBegin_"); p; p = strtok(NULL, "MspeedEnd_")) { if (h1==0) {Mspeed=atof(p);} h1++; } MotorSerial.print(Mspeed); //включаем вращение двигателя } //'MspeedMaxBegin_50000_MspeedMaxEnd_' if ( (HC12Buff.indexOf("MspeedMaxBegin")==0) and (HC12Buff.indexOf("MspeedMaxEnd")>0) ) { char charVar[HC12Buff.length()+1]; HC12Buff.toCharArray(charVar, sizeof(charVar)); char *sInput =(char *)charVar; int h1=0; for (char *p = strtok(sInput, "MspeedMaxBegin_"); p; p = strtok(NULL, "MspeedMaxEnd_")) { if (h1==0) {MspeedMax=atof(p);} h1++; } EEPROM.put(50, MspeedMax); } //'PIDBegin_200_1_2_10_PIDEnd_' if ( (HC12Buff.indexOf("PIDBegin")==0) and (HC12Buff.indexOf("PIDEnd")>0) ) { char charVar[HC12Buff.length()+1]; HC12Buff.toCharArray(charVar, sizeof(charVar)); char *sInput =(char *)charVar; int h1=0; for (char *p = strtok(sInput, "PIDBegin_"); p; p = strtok(NULL, "PIDEnd_")) { if (h1==0) {Setpoint=atof(p);} if (h1==1) {Kp=atof(p);} if (h1==2) {Ki=atof(p);} if (h1==3) {Kd=atof(p);} if (h1==4) {Kpow=atof(p);} h1++; } EEPROM.put(0, Setpoint); EEPROM.put(10, Kp); EEPROM.put(20, Ki); EEPROM.put(30, Kd); EEPROM.put(40, Kpow); myPID.SetTunings(Kp, Ki, Kd); myPID.SetOutputLimits(5000-Kpow, WindowSize); } //'TempMaxBegin_60_350_180_TempMaxEnd_' if ( (HC12Buff.indexOf("TempMaxBegin")==0) and (HC12Buff.indexOf("TempMaxEnd")>0) ) { char charVar[HC12Buff.length()+1]; HC12Buff.toCharArray(charVar, sizeof(charVar)); char *sInput =(char *)charVar; int h1=0; for (char *p = strtok(sInput, "TempMaxBegin_"); p; p = strtok(NULL, "TempMaxEnd_")) { if (h1==0) {TempMotorMax=atof(p);} if (h1==1) {TempPIDMax=atof(p);} if (h1==2) {TempPIDMin=atof(p);} h1++; } EEPROM.put(60, TempMotorMax); EEPROM.put(70, TempPIDMax); EEPROM.put(80, TempPIDMin); } //////////////////////////////// //Включение и выключение PID if (HC12Buff=="PIDStatus=1") { myPID.SetTunings(Kp, Ki, Kd); myPID.SetOutputLimits(5000-Kpow, WindowSize); myPID.SetSampleTime(1000); myPID.SetMode(AUTOMATIC); PIDStatus=1; } if (HC12Buff=="PIDStatus=0") { PIDStatus=0; myPID.SetMode(MANUAL); } //Включение и выключение PID //////////////////////////////// ////////////////////////////////////// /////Отдача в HC12 в ответ if (HC12Buff=="tab6_") { Serial.print(">_"); //Начало передачи Serial.print("TempMotorMax="); Serial.print(TempMotorMax); Serial.print("TempPIDMax="); Serial.print(TempPIDMax); Serial.print("TempPIDMin="); Serial.print(TempPIDMin); Serial.print("_<"); //Конец передачи } /////Отдача в HC12 в ответ ////////////////////////////////////// ////////////////////////////////////// /////Отдача в HC12 в ответ if (HC12Buff=="tab7_") { Serial.print(">_"); //Начало передачи Serial.print("temp1="); Serial.print(tempRound1); Serial.print("_<"); //Конец передачи } /////Отдача в HC12 в ответ ////////////////////////////////////// ////////////////////////////////////// /////Отдача в HC12 в ответ if (HC12Buff=="tab1_") { Serial.print(">_"); //Начало передачи Serial.print("temp1="); Serial.print(tempRound1); Serial.print("tempMotor="); Serial.print(tempMotorRound); Serial.print("Mspeed="); Serial.print(Mspeed); Serial.print("MspeedMax="); Serial.print(MspeedMax); Serial.print("PIDStatus="); Serial.print(PIDStatus); Serial.print("_<"); //Конец передачи } /////Отдача в HC12 в ответ ////////////////////////////////////// ////////////////////////////////////// /////Отдача в HC12 в ответ if (HC12Buff=="tab4_") { Serial.print(">_"); //Начало передачи Serial.print("Setpoint="); Serial.print(Setpoint); Serial.print("Kp="); Serial.print(Kp); Serial.print("Ki="); Serial.print(Ki); Serial.print("Kd="); Serial.print(Kd); Serial.print("Kpow="); Serial.print(Kpow); Serial.print("_<"); //Конец передачи } /////Отдача в HC12 в ответ ////////////////////////////////////// if (HC12Buff==">_BAD_<") { BadStatus=1; } //авария от протяжки HC12Buff=""; } /////Прием от HC12 с протяжки ////////////////////////////////////// ////////////////////////////////////////// ////Опрос датчиков температуры в нутри платы if ( (t1+1000) < millis()) { tempMotor.requestTemperatures(); tempMotorRound=tempMotor.getTempCByIndex(0); tempRound1=temp1.readCelsius(); t1=millis(); } ////Опрос датчиков температуры в нутри платы ////////////////////////////////////////// }
код второй ардуинки
long long char2LL(char *str) { long long result = 0; // Initialize result // Iterate through all characters of input string and update result for (int i = 0; str[i] != '\0'; ++i) result = result*10 + str[i] - '0'; return result; } void setup() { // put your setup code here, to run once: Serial.begin(9600); noTone(3); } void loop() { // put your main code here, to run repeatedly: if (Serial.available()) { String Buff; while(Serial.available()) { while(Serial.available()) { char c = Serial.read(); Buff+=c; } delay(100); } char arr[12]; Buff.toCharArray(arr, sizeof(arr)); unsigned long fq=char2LL(arr); if (fq>0) {tone(3,fq);} else {noTone(3);} Serial.println(fq); } }
Меандра она такая длинная. Нехватило сил досмотреть до конца. Можно как то урезать скетч, что бы оставить только то где глючит?
если бы я знал...
Вангую проблема в библиотеке далласа, там delay все портит
Вам не сдельно, за количество строк, оплачивают? А то пробелы, между блоками, на мысли наводят.
Та, на всякий случай, меандра, она все таки мужского рода.))))
Согласен с предыдущим оратором, убейте даллас температуре и попробуйте неблокирующий на онваре.
Та, на всякий случай, меандра, она все таки мужского рода.))))
А по моему Меандра очень романтично, только по выше приведенной "схеме" не очень ясно откуда она берется и как попадает на шаговый двигатель.
Спасибо большое. попробую убрать библиотеку DallasTemperature и вновь совместить скетчи
svm - левый нижний угол ввыход на драйвер шагового двигателя
Проблема в библиотеке датчика температуры. Её давно надо выкинуть из списка общеупотребимых из-за встроенных delay() большой длительности. Яркий пример копрокодерства недоучек..
убейте даллас температуре и попробуйте неблокирующий на онваре.
Да можно же и на ней неблокирующе писать. Я как-то выкладывал. Вылжить ещё раз?
убейте даллас температуре и попробуйте неблокирующий на онваре.
Да можно же и на ней неблокирующе писать. Я как-то выкладывал. Вылжить ещё раз?
Я ее в принципе не люблю. Если только ТС нужно.
Ну, как, очень ценная библиотека. Вот кто Вам ещё в программу float, с его двумя двумя килами памяти на ровном месте подтянет? А эта подтягивает :)
))))))