проблема с меандрой
- Войдите на сайт для отправки комментариев
Пнд, 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, с его двумя двумя килами памяти на ровном месте подтянет? А эта подтягивает :)
))))))