Датчик нуля pc814 и зависание.
- Войдите на сайт для отправки комментариев
Чт, 13/09/2018 - 19:55
Здравствуйте уважаемые эксперты. Собрал на ардуино управление нагревателем через симистор, MOC3051 и pc814. И если при старте ардуино датчик нуля подключен к 220, то ардуино виснет. Когда 220 от датчика отключено или земля датчика отключена от ардуино все работает и при подключении нагрузки все ОК. Что я сделал не так?
Ардуино запитано от повербанка 5v/
Что я сделал не так?
Неправильно посчитали номинал резистора R2, не туда припаяли синий провод и что-то невнятное написали в строе №32 скетча.
На 5 вольтах у меня 20 kOm, на 220 у меня 67 kOm. А вы про какой именно скетч говорите?
А вы про какой именно скетч говорите?
Про тот, который зависает.
А можете ссылку дать, сравню со своим?
Тролль троллит тролля.
Кто нибудь объяснит что в 32 строке?
maxpayn, Вам ненавязчиво намекают, что до тех пор, пока Вы не опубликуете схему и скетч, в которых возникают проблемы, предмет для обсуждения отсутствует.
так снова лишние сущности, нафига она вообще, 32 строка, а?
И вот тоже читаем ....
и вот спрашивается , зачем цеплять 220 и землю датчика, если все и без них прекрасно работает ?
т.е. опять лишние сущности
Была похожая проблема с 8 канальным диммером c управлением по serial. Если перезагружаешь ардуину при работающем датчике "0", то она виснет. Если включаешь датчик "0" после перезагрузки - все ОК. Вылечилось заменой библиотеки CyberLib на Nanopins
Кто нибудь объяснит что в 32 строке?
Да, кто ж её, акромя тебя-то, видел, родной?
Я здесь имел ввиду что подключаю 220 или землю уже после старта ардуино.
Я здесь имел ввиду что подключаю 220 или землю уже после старта ардуино.
Тебя в школе только писать научили, читать не?
Я изначально подумал что на форуме используется какой то стандартный скетч, вот про него и говорят. Попробую заменить свой 21кБ скетч маленьким для проверки датчака.
Я изначально подумал что на форуме используется какой то стандартный скетч, вот про него и говорят. Попробую заменить свой 21кБ скетч маленьким для проверки датчака.
Дерзайте, не могем покуситься на ваши секреты.
Тут секрет полишинеля.
#include <SmartDelay.h> //#include <IRremote.h> #include <TM1638.h> #include "max6675.h" //#include <SPI.h> //#include <Wire.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 40 #include <CyberLib.h> //Библиотека от Cyber-Place.ru volatile uint8_t tic, Dimmer1, Dimmer2 ; //uint8_t data; byte TXS = 2; #define LEFT 0 #define RIGHT 1 float theNumberToDisplay = 0; Adafruit_SSD1306 display(OLED_RESET); //int input_pin = 13; //set D13 as input signal pin //IRrecv irrecv(input_pin); //decode_results signals; TM1638 module(13, 9, 7); int Tsmax, Tsmin, SoakTime, MeltingPoint, ReflowTime, MaxPackageTemp, TsmaxMP; byte keys, keysFor; int thermoDO = 5; //он же SO int thermoCS = 4; int thermoCLK = 3; //он же SCK float SPHeatST, Input1, Input2; int thermoDO2 = 12; //он же SO int thermoCS2 = 11; int thermoCLK2 = 10; //он же SCK byte xxx, kdp, STMaxPower, tempToswitch; byte stage = 0; MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); MAX6675 thermocouple2(thermoCLK2, thermoCS2, thermoDO2); byte tZ = 0; char lcd_buffer[16]; // Массив для вывода int stb1, ste1, stb2, ste2; byte displayDigits[] = {63,6,91,79,102,109,124,7,127,103 }; byte values[] = { 0,0,0,0,0,0,0,0 }; int theDigits[] = { 0,0,0,0,0,0 }; // переменные для калмана "ВЕРХНЕГО" нагревателя float varTerm1 = 0.25; // среднее отклонение (ищем в excel) float varProcess1 = 0.025; // скорость реакции на изменение (подбирается вручную) float Pc1 = 0.0; float G1 = 0.0; float P1 = 1.0; float Xp1 = 0.0; float Zp1 = 0.0; float Xe1 = 0.0; // переменные для калмана "НИЖНЕГО" нагревателя float varTerm2 = 0.25; // среднее отклонение (ищем в excel) float varProcess2 = 0.025; // скорость реакции на изменение (подбирается вручную) float Pc2 = 0.0; float G2 = 0.0; float P2 = 1.0; float Xp2 = 0.0; float Zp2 = 0.0; float Xe2 = 0.0; unsigned long currentMillisv2, currentMillisv3; unsigned long currentMillis, currentMillisv, currentMillisMP; unsigned long start, finished, elapsed; byte zash, zashv, zashvMP; int tA; //long loopTime; void st3(long interv, byte tm) { if (zash == 0) { currentMillis = millis(); zash = 1; } if (millis() - currentMillis >= interv * 1000) { zash = 0; Tsmin++; if (tm == 1) { // MeltingPoint--; } } } void stMP(long interv, byte tm) { if (zashvMP == 0) { currentMillis = millis(); zashvMP = 1; } if (millis() - currentMillisMP >= interv * 1000) { zashvMP = 0; TsmaxMP++; if (tm == 1) { //MeltingPoint--; } } } bool vremyaMy(byte intervv) { if (zashv == 0) { currentMillisv = millis(); zashv = 1; } if (millis() - currentMillisv >= intervv * 1000) { // zashv = 0; return true; } else { return false; } } int DisplayResult(char n) { finished = millis(); // saves stop time to calculate the elapsed time // declare variables float h, m, s, ms; unsigned long over; // MATH time!!! elapsed = finished - start; h = int(elapsed / 3600000); over = elapsed % 3600000; m = int(over / 60000); over = over % 60000; s = int(over / 1000); ms = over % 1000; // display the results if (n == 'm') { return (m); } if (n == 's') { return (s); } if (n == 't') { return (m * 60 + s); } } int DeltaST; void setup() { Tsmin = 165; Tsmax = 185; SoakTime = 150; MeltingPoint = 210; ReflowTime = 50; MaxPackageTemp = 235; kdp = 5; DeltaST = Tsmax - Tsmin; module.setDisplay(values); module.setupDisplay(true, 2); // where 7 is intensity (from 0 to 7) SPHeatST = SoakTime / DeltaST; Dimmer2 = 250; Dimmer1 = 250; stage = 0; // irrecv.enableIRIn(); // enable input from IR receiver D6_Out; D8_Out; //Настраиваем порты на выход D6_High; D8_High; //установить на выходах низкий уровень сигнала D2_In; //настраиваем порт на вход для отслеживания прохождения сигнала через ноль //CHANGE – прерывание вызывается при любом изменении значения на входе; //RISING – вызов прерывания при изменении уровня напряжения с низкого (Low) на высокий(HIGH) //FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкий (Low) attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень StartTimer1(halfcycle, 40); //время для одного разряда ШИМ StopTimer1(); //остановить таймер // tempSR1 = 0; // i = 0; // tempSR1m = 0; Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //активируем питание и землю // pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH); // pinMode(vccPin2, OUTPUT); digitalWrite(vccPin2, HIGH); //pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW); //Serial.println("MAX6675 test"); //ждем стабилизации чипа MAX //delay(500); } void halfcycle() //прерывания таймера { tic++; //счетчик if (Dimmer1 < tic ) D6_High; //управляем выходом if (Dimmer2 < tic ) D8_High; //управляем выходом //управляем выходом } void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту { tic = 0; //обнулить счетчик ResumeTimer1(); //запустить таймер attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик } void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту { StopTimer1(); //остановить таймер D6_Low; D8_Low; //логический ноль на выходы tic = 0; //обнулить счетчик attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик } float filter1(float val_1) { //функция фильтрации показений "Верхней" термопары Pc1 = P1 + varProcess1; G1 = Pc1 / (Pc1 + varTerm1); P1 = (1 - G1) * Pc1; Xp1 = Xe1; Zp1 = Xp1; Xe1 = G1 * (val_1 - Zp1) + Xp1; // "фильтрованное" значение return (Xe1); } float filter2(float val_2) { //функция фильтрации показений "Нижней" термопары Pc2 = P2 + varProcess2; G2 = Pc2 / (Pc2 + varTerm2); P2 = (1 - G2) * Pc2; Xp2 = Xe2; Zp2 = Xp2; Xe2 = G2 * (val_2 - Zp2) + Xp2; // "фильтрованное" значение return (Xe2); } float speedtemp(byte stTD) { float st1, st2; if (stTD == 2) { st2 = Input2 - stb2; stb2 = Input2; return (st2); } if (stTD == 1) { st1 = Input1 - stb1; stb1 = Input1; return (st1); } } int PowerControl(int dlt, byte TD) { int st1, st2; if (TD == 2) { Dimmer2 = Dimmer2 + dlt; } if (TD == 1) { Dimmer1 = Dimmer1 + dlt; } if (Dimmer2 < 5) { Dimmer2 = 5; } if (Dimmer2 > 200) { Dimmer2 = 195; } if (Dimmer1 < 5) { Dimmer1 = 5; } if (Dimmer1 > 194) { Dimmer1 = 250; } } byte p; //char* NameProf[] = {"Down Only ", "E216-0752001", "Ext Pb 200", "EPbFree 230", "S215-0752007", "This is string 6"}; SmartDelay vremya1(1000000UL); //SmartDelay vremya3(3000000UL); SmartDelay vremya4(500000UL); //com port SmartDelay vremya5(5000000UL); SmartDelay vremya6polka2(25000000UL); //SmartDelay vremya7(5000000UL); SmartDelay vremyaDU(500000UL); SmartDelay vremyaDelay(2000000UL); void displayNumber(float numberToSplit, int whichSide, int numOfDPs){ // The number to be split should be a float from 0 to 99.9999 // If is below zero or equal to or over 100, then just display ----. // numOfDPs is the number of digits after the point, only 1 or 2 are acceptable values if(numOfDPs > 2 or numOfDPs < 1)numOfDPs = 1; // Extract the digits from this number. numberToSplit = (int)(100 * numberToSplit); theDigits[0] = (int)(numberToSplit/10000); theDigits[1] = (int)((numberToSplit - (10000*theDigits[0])) / 1000); theDigits[2] = (int)((numberToSplit - (10000*theDigits[0]) - (1000*theDigits[1]))/100); theDigits[3] = (int)(numberToSplit - (10000*theDigits[0]) - (1000*theDigits[1]) - (100*theDigits[2]))/10; //theDigits[4] = (int)(numberToSplit - (10000*theDigits[0]) - (1000*theDigits[1]) - (100*theDigits[2])- (10*theDigits[3])); // Find and store the byte variables required to show these digits int dispDig[4]; if(theDigits[0] == 0) dispDig[0] = 0; // Hide a leading zero if there is one else dispDig[0] = displayDigits[theDigits[0]]; dispDig[1] = displayDigits[theDigits[1]] ; // Apend the dp onto the second digit dispDig[2] = displayDigits[theDigits[2]]; dispDig[3] = displayDigits[theDigits[3]+128]; //dispDig[4] = displayDigits[theDigits[4]]; // If we are only showing one DP, then leave last character blank to make things more legible on the display if(numOfDPs == 1) dispDig[3] = 0; // Make sure that the number passed to the function was >= 0 or <100, otherwise show an error with ----. if(numberToSplit/100 < 0 or numberToSplit/100 >= 250){ for(int i = 0; i < 5; i++) dispDig[i] = 64; } // Find if number to be shown on the left or the right side of the display int offset = 0; // LEFT by default if(whichSide == RIGHT) offset = 4; // Update the values in the values array used by the display. values[0+offset] = dispDig[0]; values[1+offset] = dispDig[1]; values[2+offset] = dispDig[2]; values[3+offset] = dispDig[3]; //values[4+offset] = dispDig[4];; // Update the display itself with the new values. module.setDisplay(values);} void loop() { // Where do you want to show the number, on the LEFT side, or the RIGHT of the display? int positionToDisplayIt = LEFT; // How many decimal places to show - must be 1 or 2 in this example code int numberOfDecimalPlacesToShow = 2; // Call the function to display the number //displayNumber(theNumberToDisplay, positionToDisplayIt, numberOfDecimalPlacesToShow); if (stage == 0) { tZ = round(Input1); } tA = tZ + DisplayResult('t'); { Input1 = (filter1(thermocouple.readCelsius())); Input2 = (filter2(thermocouple2.readCelsius())); //byte values[] = {Input1,Input2}; //module.setDisplayToDecNumber(values,0,false); //void displayNumber(float numberToSplit, int whichSide, int numOfDPs if (vremya4.Now()) { Serial.println(round(Input1)); Serial.println (round(Input2)); Serial.println ((tA - tZ)); Serial.println (Dimmer1); Serial.println (Dimmer2); displayNumber(Input1,0,0); displayNumber(Input2,1,0); // disp.display(0, (Input1 /100) % 10); //theDigits[0] = (byte)(Input1 / 1000) % 10; //module.display(theDigits); // module.setDisplay(theDigits); } //module.setupDisplay(true, 7); keys = module.getButtons(); module.setLEDs(keys); //Serial.println (keys); module.setLEDs(keysFor); //module.setDisplayToHexNumber(0x1, 0xF0); if (keys==0) { } if (keys==1) { //Desk Lead Tsmin = 140 ; Tsmax = 165; SoakTime = 120; MeltingPoint = 205; ReflowTime = 50; MaxPackageTemp = 220; kdp = 4; p = 1; STMaxPower = 100; tempToswitch = 9; stage = 1; keysFor=1; } if (keys==2) { //Desk FreeLead Tsmin = 170 ; Tsmax = 190; SoakTime = 150; MeltingPoint = 230; ReflowTime = 50; MaxPackageTemp = 245; kdp = 4; p = 2; STMaxPower = 85; //было 95 при 27, а при 25 градусах сделал 85 tempToswitch = 9; stage = 1; keysFor==2; } if (keys==4) { //Note Lead S3 Tsmin = 140 ; Tsmax = 165; SoakTime = 120; MeltingPoint = 200; ReflowTime = 50; MaxPackageTemp = 220; STMaxPower = 105; tempToswitch = 13; //при 28 в комнате примерно 16 kdp = 4; p = 3; stage = 1; keysFor==4; } if (keys==8) { //Note LeadFree S4 Tsmin = 170 ; Tsmax = 190; SoakTime = 150; MeltingPoint = 235; ReflowTime = 50; MaxPackageTemp = 245; STMaxPower = 105; tempToswitch = 6; kdp = 4; p = 4; stage = 1; keysFor==8; } if (keys==16) { //Down Only S5 Tsmin = 200; kdp = 4; p = 5; stage = 9; keysFor=16; } if (keys==64) { //only top s7 stage = 8; keysFor=64; } if (keys==128) { //Power Off stage = 10; keysFor=128; } } /* if (irrecv.decode(&signals)) { if (signals.value == 2155822020) { stage = 10; } if (signals.value == 2155811310) { } if (signals.value == 2155845990) { TXS = 1; } if (signals.value == 2155840380) { TXS = 2; } if (signals.value == 2155825590) { //Down Only Tsmin = 200; kdp = 4; p = 1; stage = 9; } if (signals.value == 2155858230) { //Desk Lead Tsmin = 140 ; Tsmax = 165; SoakTime = 120; MeltingPoint = 205; ReflowTime = 50; MaxPackageTemp = 220; kdp = 4; p = 2; STMaxPower = 100; tempToswitch = 9; stage = 1; } if (signals.value == 2155819980) { //Desk FreeLead Tsmin = 170 ; Tsmax = 190; SoakTime = 150; MeltingPoint = 230; ReflowTime = 50; MaxPackageTemp = 245; kdp = 4; p = 3; STMaxPower = 95; tempToswitch = 9; stage = 1; } if (signals.value == 2155835790) { //Note Lead Tsmin = 140 ; Tsmax = 165; SoakTime = 120; MeltingPoint = 200; ReflowTime = 50; MaxPackageTemp = 220; STMaxPower = 105; tempToswitch = 13; //при 28 в комнате примерно 16 kdp = 4; p = 4; stage = 1; } if (signals.value == 2155868430) { //Note LeadFree Tsmin = 170 ; Tsmax = 190; SoakTime = 150; MeltingPoint = 235; ReflowTime = 50; MaxPackageTemp = 245; STMaxPower = 105; tempToswitch = 6; kdp = 4; p = 5; stage = 1; } if (signals.value == 2155811820) { Tsmin = 200; kdp = 4; p = 6; stage = 9; } if (signals.value == 2155824060) { STMaxPower = STMaxPower - 5; } if (signals.value == 2155815390) { STMaxPower = STMaxPower + 5; } irrecv.resume(); } */ if (vremyaDU.Now()) { if (stage == 0) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("1-DLead, 2-DLeadFree,3-NLead, 4-NLeadFree,5-DownO, 7-TestingTD,8-PWOff"); display.display(); } else { display.clearDisplay(); display.setTextSize(TXS); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(round(Input1)); display.print(" S"); display.print(stage); display.setTextSize(1); display.print(" LPD "); display.println(STMaxPower); display.setCursor(78, 8); display.print(DisplayResult('m')); display.print(":"); if (DisplayResult('s') < 10) { display.print("0"); } display.print(DisplayResult('s')); display.setTextSize(2); display.setCursor(0, 16); // get the next signal // display.println(Dimmer2); display.print(round(Input2)); display.print(" "); display.setTextSize(1); display.print(" P"); display.print(p); display.print(" T"); display.print(Dimmer1); display.print(" D"); display.print(Dimmer2); display.setCursor(39, 24); //display.print(" "); display.print(Tsmin); display.print(" "); display.print(Tsmax); display.print(" "); display.print(MeltingPoint); display.print(" "); display.print(speedtemp(1)); // display.println(NameProf[p]); display.display(); } } delay(150); //preheat switch (stage) { case 1: TsmaxMP = Tsmax; if (Dimmer2 > 150) { Dimmer2 = 150; } if (vremyaDelay.Now()) { if (speedtemp(1) < 1) { PowerControl(-kdp, 2); } if (speedtemp(1) > 2) { PowerControl(kdp, 2); } if (Input1 >= Tsmin - 3) { PowerControl(kdp, 2); } if (xxx == 0) { if (Input1 >= Tsmin - 5) { PowerControl(200 - ((((200 - Dimmer2) / 2) - 17) * 2) , 2); xxx = 1; kdp = 2; } } if (Input1 >= Tsmin - tempToswitch) { Dimmer2 = 170; //PowerControl(50, 2); stage = 2; } } // Dimmer1 = 250; break; //Soak case 2: if (Dimmer2 < STMaxPower) { Dimmer2 = STMaxPower; } if (Dimmer2 > 50 + STMaxPower) { Dimmer2 = 50 + STMaxPower; } if (vremyaDelay.Now()) { if (Input1 < Tsmin ) { PowerControl(-1, 2); } if (Input1 > Tsmin ) { PowerControl(1, 2); } } st3(SPHeatST , 0); if (Input1 >= Tsmax) { stage = 3; } if (Input1 - Tsmin >= 2 and Input1 - Tsmin <= 3) { if (vremya5.Now()) { PowerControl(5, 2); } } if (Input1 - Tsmin <= -2 and Input1 - Tsmin >= -3) { if (vremya5.Now()) { PowerControl(-5, 2); } } if (Input1 - Tsmin >= 3 and Input1 - Tsmin <= 4) { if (vremya5.Now()) { PowerControl(10, 2); } } if (Input1 - Tsmin <= -3 and Input1 - Tsmin >= -4) { if (vremya5.Now()) { PowerControl(-10, 2); } } break; case 3: if (vremyaDelay.Now()) { if (Input1 < Tsmax ) { PowerControl(-1, 2); } if (Input1 > Tsmax ) { PowerControl(1, 2); } if (vremya6polka2.Now()) { stage = 4; Dimmer1 = (((200 - Dimmer1) / 2) - 85) * 2; Tsmax = Input2 + 5; xxx = 0; kdp = 5; } } break; case 4: if (vremya1.Now()) { if (Input2 < Tsmax) { PowerControl(-5, 2); } if (Input2 > Tsmax) { PowerControl(5, 2); } if ( TsmaxMP > MeltingPoint ) { TsmaxMP = MeltingPoint ; } if (Input1 < TsmaxMP ) { PowerControl(-kdp, 1); } if (Input1 > TsmaxMP ) { PowerControl(kdp, 1); } } if (Input1 < MeltingPoint) { stMP(0.5, 0); } if (xxx == 0) { if (Input1 >= MeltingPoint - 1) { PowerControl(45, 1); xxx = 1; kdp = 2; } } if (Input1 >= MaxPackageTemp - 5) { stage = 5; } if (Input1 >= MeltingPoint) { if (vremyaMy(ReflowTime)) { stage = 6; } } break; case 5: Dimmer1 = 250; Dimmer2 = 250; break; case 6: /* delay(1000); if (Input2 > MeltingPoint - 1.5) { PowerControl(15, 2); } st3(0.1,1); */ Dimmer1 = 250; Dimmer2 = 250; break; case 8: Dimmer1 = 1; Dimmer2 = 1; break; case 9: if (Dimmer2 < STMaxPower) { Dimmer2 = STMaxPower; } if (Dimmer2 > 50 + STMaxPower) { Dimmer2 = 50 + STMaxPower; } if (vremyaDelay.Now()) { if (Input1 < Tsmin ) { PowerControl(-1, 2); } if (Input1 > Tsmin ) { PowerControl(1, 2); } break; case 10: Dimmer1 = 250; Dimmer2 = 250; break; } } }215 строку закиньте в конец loop и вызывайте один единственный раз в первом проходе. В чем косяк объяснить не могу, левел не тот. У меня не зависало, но диммер не работал если прерывание объявлял в сетапе.
Спасибо, перенос инициализации прерывания в конец loop помог, ардуино стартует,лампы нагрева вспыхивают, ардуино подвисает, перезагружается и стартует нормально. Интересный эффект конечно.
ардуино стартует,лампы нагрева вспыхивают, ардуино подвисает, перезагружается и стартует нормально. Интересный эффект конечно.
Таки код из тебя выклянчили, теперь начнём клянчить схему подключения. Когда смилостивишься и дашь,можем посмотреть почему нагрузка всё рушит.
Подключал по подобной схеме, только номиналы другие там были.
У вас полную схему хотят увидеть, да и фото не помешало бы. Я ставлю на помеху при первом открытии симистора.
Вас просили не "подобную", а Вашу схему, вместе с нагрузкой, которой здесь нет вовсе.
Схемы у меня нет. Нагрузка в виде ламп сидит на китайских диммерах, выпаял из них переменные резисторы и припаял провода с выхода MOC3051.
Ну, на нет и суда нет.
Хочеш чтоб эта схема работала? выдерни подтяжку на 5вольт, и зацепи на аналог, я сделал так и о чудо. Работает!!! и резюки на 51к у меня стоят
Хочеш чтоб эта схема работала? выдерни подтяжку на 5вольт, и зацепи на аналог, я сделал так и о чудо. Работает!!! и резюки на 51к у меня стоят
Понадобилась мне доп память, поменял на Атмегу 2560 и эта проблема ушла. Спасибо, на будующее пригодится.