Зависает Arduino nano

22580
Offline
Зарегистрирован: 20.09.2016

Всех приветствую, столкнулся с проблемой( Ардуино нано на 328 меге занимается регулировкой температуры по средством управления симмистором. Датчик температуры термопара+MAX6675. Симмистор управляется через MOC3023. так же имеется схемка детектор нуля сети.Сначала управлял по средством нескольких ступеней мощности. Типа чем ближе к реаьная температура к заданию тем меньше мощности. Все заработало корректно и как надо, но слишком сложно и долго подбирать мощности на ступени, и в итоге всеравно плавает температура критично. Решил замутить ПИД регулятор. библиотека гуглится на "раз два"Внедрил в код библиотеку скомпилировалось с первого раза=) подал питание на ардуино, сеть подавать не стал, в порт вывел значение выхода пид регулятора. работает нормально, выход регулируется все хорошо. как только подаю сетевое питание и ардуина начинает обрабатывать детектор нуля все начинает тормозить...Вот ссылка на скетч.

Я подозреваю что ардуине не хватает производительности.. ПИД регулятор сжирает мощ, а тут еще и внешнее прерывание обрабатывать надо, да еще и по таймеру, вот она и сдается?

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а вы его под наши сети адаптировали?

22580
Offline
Зарегистрирован: 20.09.2016

Кого именно? Детектор нуля работает исправно, вся схема управления симмистором работает корректно. пока не добавишь ПИД регулятор. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

22580 пишет:

Кого именно? Детектор нуля работает исправно, вся схема управления симмистором работает корректно. пока не добавишь ПИД регулятор. 

я о скетче, он под сети 60 герц
ПРиведите ваш зависающий скетч

22580
Offline
Зарегистрирован: 20.09.2016

в коментариях написано какие нужно ставить параметры для 60 герц. стоят на 50. 

22580
Offline
Зарегистрирован: 20.09.2016

В общем перенастроил пид под релейный режим управления, отключил детектор нуля. просто подаю на мос3023 сигнал с выходя ПИД регуятора. Все работает, но при уставке 200 температура плавает от 180 до 280...  кто подскажет про подбор коэффициентов?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

никто, хрустального шара нету, разве непонятно, что без публикации рабочего скетча разговор ни о чём

22580
Offline
Зарегистрирован: 20.09.2016

Ты угараешь? Скетч в первом посте. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Скетч выглядит как-то так, в первом посте в упор этого не увидел
 

#include <Wire.h>             
 #define  ADR_ASD1115  0x48   //адрес ads1115
 
 byte writeBuf[3];            //для конфигурирования АЦП три байта
 byte readBuf[3];             //для чтения данных из АЦП три байта 

 float myfloat;               
 const float VPS = 6.144 / 32768.0;  //вольт на шаг в зависимости от PGA  усиления АЦП тут для 6.144
 unsigned int val = 0;        
//-------------------------------------------------------------------------------
 void setup() {
 Serial.begin(9600); 
 Wire.begin();              // begin I2C
 }  
//--------------------------------------------------------------------------------

 void loop() {                
 config_ads115();            // Конфигурирование и запуск преобразования ads1115 
 get_config();               // Прочитать конфиг биты и вывести на экран
 get_voltage();              // Прочитать регистр преобразования, пересчитать в напряжение
 
}
//-------------------------------------------------------------------------------
 void config_ads115(){        // Конфигурирование и запуск преобразования ads1115
   
   writeBuf[0] = 1;           // Указатель регистра (Conversion register is 0b00000000; config register is 0b00000001,
                              // Lo_thresh register is 0b00000010;Hi_thresh register is 0b00000011) т.е. указали конфиг
                              
   writeBuf[1] = 0b10000000;  // биты с 15 по 8 конфигурации смотрим в даташите сами
                              

   writeBuf[2] = 0b10000011;   // биты с 7 по 0 конфигурации смотрим в даташите сами
                                
  Wire.beginTransmission(ADR_ASD1115);  //конфигурируем АЦП записью трех байт 
  Wire.write(writeBuf[0]);     // Указатель регистра
  Wire.write(writeBuf[1]);     // биты с 15 по 8 конфигурации
  Wire.write(writeBuf[2]);     // биты с 7 по 0 конфигурации
  Wire.endTransmission();  

  delay(500); 
 }  

//-------------------------------------------------------------------------------
 void get_voltage(){                   // Прочитать регистр преобразования, пересчитать в напряжение
  readBuf[0] = 0;                      // Указатель регистра (Conversion register is 0b00000000; config register is 0b00000001,
                                       // Lo_thresh register is 0b00000010;Hi_thresh register is 0b00000011)т.е. указали Conversion 
                                    
  Wire.beginTransmission(ADR_ASD1115); // Начали читать данные из регистра преобразования 
  Wire.write(readBuf[0]);              // pointer указал в readBuf[0] записан 0 т.е. регистр преобразования
  Wire.endTransmission();

  Wire.requestFrom(ADR_ASD1115, 2);    // читаем из АЦП два байта
  readBuf[1] = Wire.read();  // 
  readBuf[2] = Wire.read();  // 
  Wire.endTransmission();  

                                     
  val = readBuf[1] << 8 | readBuf[2];  // собираем два байта в кучу в переменную int val

  if (val > 32768) val = 0;
  
  myfloat = val * VPS;                 // пересчитываем в напряжение
  
  Serial.print("Sensor voltage = ");   // вывод на экран результата
  Serial.println(myfloat);
 
 } 
//--------------------------------------------------------------------------------
 void get_config(){                    // взять все биты конфига и вывести на экран
  readBuf[0] = 1;                      // Указатель регистра (Conversion register is 0b00000000; config register is 0b00000001,
                                       // Lo_thresh register is 0b00000010;Hi_thresh register is 0b00000011) т.е. указали config
                                    
  Wire.beginTransmission(ADR_ASD1115); // Начали читать данные из регистра конфига 
  Wire.write(readBuf[0]);              // pointer указал в readBuf[0] записан 1 т.е. регистр config
  Wire.endTransmission();

  Wire.requestFrom(ADR_ASD1115, 2);    // читаем из АЦП два байта
  readBuf[1] = Wire.read();  // 
  readBuf[2] = Wire.read();  // 
  Wire.endTransmission();  

  Serial.print("Config = ");           //выводим на экран все биты конфига
  Serial.print(readBuf[1],BIN);
  Serial.print("_");
  Serial.println(readBuf[2],BIN);
 
 } 

//-------------------------------------------------------------------------------

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Клапауций вроде не запрещал жеж

22580
Offline
Зарегистрирован: 20.09.2016

ну ясно...

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

22580 пишет:
Я подозреваю что ардуине не хватает производительности..

Не может быть.
С чего сделан вывод о зависании?
Вы в курсе, что MAX6675 требует время для преобразования не менее 0,22 сек по ДШ?

Цитата:
В общем перенастроил пид под релейный режим управления

Что в качестве нагрузки? Тэн в воде или паяльный фен?

Цитата:
кто подскажет про подбор коэффициентов?

Гугл.
Самое простейшее - "ПИД управление в нестрогом изложении".

22580
Offline
Зарегистрирован: 20.09.2016

Я забирают данные с МАХ раз в 300мс по таймеру. В качестве нагрузки фен.
Вывод о зависание сделан из следующего: какттолько подарю сетевое питание данные в порт начинают сдаться намного медленнее при попытке регулировать задание, происходит очень медленно она. Задание задается потенциометром+АЦП кручу ручку и данные очень медленно обновляются на экранчике.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Все беды из-за delay-ев в прерывании - нормально работать не будет, т.к. почти всё процессорное время тратится на него.
Задержку относительно зеро-кросс нужно делать на аппаратном таймере.

У меня нано рулит паяльником (ШИМ), феном (ФИ) и всё это может работать одновременно, не мешая друг-другу.

22580
Offline
Зарегистрирован: 20.09.2016

Можно на код взглянуть?

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Тут

ЗЫ. С MAX6675 температура будет измеряться с погрешностью, чем выше вы зададите, тем больше будет разница температуры потока воздуха со значением, что выдаст 6675 (у меня она была до 60 град.)

22580
Offline
Зарегистрирован: 20.09.2016

Мне бы добиться равномерности температуры. А там уже вводить коррективы можно.