Sari la conținut

Mihai3

Tehnium Azi
  • Număr conținut

    1.037
  • Înregistrat

  • Ultima Vizită

  • Zile Câștigate

    12

Orice postat de Mihai3

  1. Am rezolvat. Am găsit exact piesa de care aveam nevoie într-un ștecher. Mulțumesc !
  2. Am folosit pistolul de lipit despre care am discutat în acest topic până acum câteva zile, când am decis să desfac carcasa și să îi fac o revizie. Totul pare ok, numai că nu prea aveam încredere în sistemul de prindere al cablului, care are rolul de a asigura cablul în caz că este smucit. L-am înlocuit folosind o presetupă pg7 tăiată pe la jumătate și am prins cu aceasta cablul, pentru a nu se rupe firele în cazul în care este smucit. As dori sa știu si părerea dvs, poate mă ajutați cu o idee mai bună. Ideal ar fi să folosesc sistemul de prindere pentru cablu cu cele 2 șuruburi și bucata aceea de metal, dar nu am bucata aceea de metal și nici nu găsesc ceva compatibil în atelierul meu. Vă mulțumesc !
  3. Am o anexă, în curtea casei, construită demult, care a avut inițial instalația electrică proiectată cu siguranțe 1P: 1 siguranță generală C32, 3 siguranțe C25 pentru prize (1 pt mașina de spălat, 1 pt bucătărie, 1 pt restul anexei - adică cele 3 încăperi mici) și 2 siguranțe C16 pentru iluminat (1 pt bucătărie și exterior, 1 pt cele 3 încăperi). Conductoarele folosite sunt de 2.5mmp pentru prize, 1.5mmp pentru iluminat și 1.5mmp pentru împământare. Înainte (în amonte) de siguranța C32, a fost instalat un contor electric. Aș dori să schimb siguranțele cu B16 pentru prize și B10 sau B6 pentru iluminat. Mi s-a recomandat să folosesc siguranțe 1P+N (1 pol + nul, adică siguranțe care declanșează pe fază dar care întrerup si nulul). Anexa este alimentată cu un cablu CYY-F 3x6mmp, din care sunt folosite numai 2 conductoare, al treilea fiind lăsat liber în tablou. Acest cablu CYY-F pornește direct de la tabloul casei principale și merge până în tabloul anexei. Împământarea anexei este realizată separat față de împământarea casei principale. La casa principală, atât nulul cât și împământarea sunt conectate în tabloul de la exterior, care conține contorul electric și o fuzibilă de 25A, de pe peretele casei, în același punct. Am identificat fiecare fază care pleacă din tablou spre prize și spre becuri si fiecare nul care ii corespunde. Astfel aș putea folosi siguranțe 1P+N. Apoi am văzut ca pe siguranța comună pentru cele 3 încăperi mici sunt conectate 3 circuite de prize și le-am separat, din dorința ca în situația în care există o problemă la un circuit, atunci să nu cadă curentul în toate cele 3 încăperi. Deci am ajuns la 5 siguranțe pentru prize și 2 siguranțe pentru iluminat. Și mai vreau sa pun și o sonerie. Ideal, era să chem un electrician, numai că, dacă venea unul identic cu primul, probabil ca ajungeam la fel de bine (a montat C25 pt prize si C16 pt iluminat). 1. Are rost sa folosesc siguranțe 1P+N sau mai bine merg tot pe 1P ? 2. Daca ar fi să folosesc siguranțe 1P+N, atunci voi avea nevoie sa prelungesc conductoarele de nul din tablou care ajung in acest moment la bara de nul (care este in partea de sus a tabloului), dar care vor trebui sa ajungă în partea de jos a tabloului, la ieșirea fiecărei siguranțe. Ce pot folosi pentru prelungire ? Cleme Wago pentru conductor FY ? 3. Soneria se poate conecta la circuitul de lumini (ultima siguranță B10) ?
  4. Da, imi cer scuze ca nu am specificat de la inceput, ca modificarea este pentru a putea slefui lemnul. Intr-adevar, cel mai bine e cu masina de slefuit. Masina de slefuit are si avantajul ca poate fi conectata la un aspirator de praf.
  5. Multumesc pentru raspunsuri. Sunt valabile cele 2 raspunsuri si in cazul in care folosesc flexul la slefuit o scandura ? sau la slefuit o bucata de metal ? Am slefuit ieri 6 scanduri cu disc abraziv (P80) si s-a comportat bine, scandurile au iesit ok.
  6. Am construit schema atașată si am verificat-o cu un bec de 70W/230V și apoi cu un flex de 720W. Motorul este un motor universal cu perii. A funcționat Ok. Circuitul de soft start trebuie pornit în același moment cu pornirea flexului, si am schimbat cablul de alimentare al flexului (care era de 2x1mmp) cu un cablu 3x1.5mmp (aș fi dorit 3x1mmp, dar nu am). Apoi am conectat ca în schema de mai jos (B1 și notațiile cu roșu): Am câteva nelămuriri legate de conectarea motorului și a soft starter-ului: 1. Am citit ca exista mai multe moduri în care un motor se poate conecta la sursa de curent alternativ. În situația mea, am lăsat motorul și periile colectoare conectate așa cum erau când am cumpărat flex-ul, adică 2 cabluri merg la bobinele statorului (de la întrerupător), apoi 2 cabluri ies din bobinele statorului si merg la periile colectoare. Există vreo modalitate mai bună de conectare ? care ar fi aceasta ? 2. În schema originală (cea de pe forumul Radiokot.ru) este precizat că se întrerup ambele fire care merg la soft starter. Este corect și dacă se întrerupe un singur conductor (cel menționat pe schema de mai sus) ? 3. Când am desfăcut carcasa flexului, am găsit un condensator (0.22uF/275V), care era conectat la întrerupător, la 2 contacte diferite de cele care mergeau la motor. Mai este necesar acest condensator ?
  7. Linia are aceeasi culoare cu layer-ul bottom, dar se poate observa ca are alta structura numai daca se face zoom (vedeti captura atasata).
  8. Linia este stratul bRestrict, care are rolul de a impiedica planul de pe stratul bottom in zona respectiva. Folosesc Eagle 9.6.2.
  9. Gasiti atasata noua versiune de layout pcb. *) am sters **) am incercat sa fac o aranjare mai frumoasa ***) am eliminat thermal pad-urile ****) conectorii (blocurile terminale) sunt de 16A fiecare
  10. Am reamplasat C8,C9,D4,Q8,R13,C4 si conectorul de la iesire. La DRC check returneaza "no errors".
  11. Radiatorul va fi amplasat fata de cablaj ca in imaginea atasata (paralel). Nu ma intereseaza in mod special sa fie PCB-ul cu conectorii dispusi inspre PCB-ul care se monteaza pe radiator, ci doar sa fie corect din punct de vedere al regulilor de realizare.
  12. Am modificat si sper ca este mai bine. Gaurile de prindere le pot elimina, nu sunt necesare.
  13. Revin cu un cablaj nou pentru o sursa liniara de data aceasta. Schema este atasata, iar pe schema am facut cateva comentarii. Schema nu imi apartine, poate doar cateva mici modificari. Cablajul este realizat pentru schema atasata, exceptand portiunile incadrate cu rosu, cu verde si partea din dreapta condensatorului C8 (de pe iesire). Partea din dreapta condensatorului C8 este un "switch load", care este inclus pe un alt pcb, pentru a putea fi conectat la sursa care se testeaza (am testat mai multe scheme diferite cu acesta). Am realizat layout-ul in Eagle incercand sa aplic metoda B descrisa de @donpetru Va rog sa aruncati o privire pe layout, si sa imi spuneti ce trebuie modificat:
  14. Care este polaritatea corecta din schemele de mai jos pentru VT3 (schema1) respectiv Q2 (schema2) ? In schema finala vad ca persoana care a construit circuitul l-a pus invers fata de schema originala ...
  15. Buna ziua, ma intereseaza si pe mine un variator de tensiune pentru flex. Am incercat cu un variator recuperat dintr-un aspirator de 2000W (acest variator foloseste un CI U2008B - care din cate am inteles se gaseste mai greu) dar ii lipseste functia soft start, adica flexul imi porneste brusc si scutura mana, ceea ce este neplacut. Am nevoie, daca cunoasteti, de o schema cu soft start si variator de viteza. Flexul este un Makita, 720W, 125mm. Va multumesc anticipat.
  16. Detin un flex (polizor unghiular) Makita de 125mm si doresc sa achizitionez pentru acesta un dispozitiv de colectare a prafului. La magazinele online pretul unui astfel de dispozitiv (original Makita) este de aprox. 200 lei. Doresc sa folosesc flexul pentru slefuirea unor lemne, pe langa debitarea si slefuirea de metale. Dar de colectarea prafului am nevoie numai la slefuirea lemnelor. As dori sa stiu daca, cunoaste cineva un astfel de dispozitiv de colectare a prafului care este mai ieftin si care sa se potriveasca cu flexul meu (model GA5030R) ? (nu e obligatoriu sa fie original de la Makita)
  17. Acestea sunt codul și capturile de ecran de pe osciloscop: DS0146 și DS0147 - pe rezistența letconului. DS0134 și DS0138 - galben=semnalul de trecere prin zero, albastru=ieșirea (pin 7). Aștept păreri/comentarii/sfaturi. #include <TimerOne.h> #include <PID_v1.h> #include <max6675.h> #include <LiquidCrystal.h> #include <SPI.h> #include <Wire.h> #define thermoDO 12 #define thermoCS 10 #define thermoCLK 13 #define potentiometer A0 #define zerocrossing 2 #define relay A1 float realTemperature; int pottemperature; LiquidCrystal lcd(3, 4, 5, 6, 8, 9); byte thermometer[8] = //icon for termometer { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 }; byte arrow[8] = //icon for arrow { B11000, B01100, B00110, B00011, B00011, B00110, B01100, B11000 }; MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); double Setpoint, Input, Output; double aggKp = 4, aggKi = 0.2, aggKd = 1; double consKp = 1, consKi = 0.05, consKd = 0.25; PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT); volatile int i = 0; //counter variable volatile boolean zero_cross = 0; // Boolean to store a "switch" to tell us if we have crossed zero int triac = 7; // Output to Opto Triac int dim = 0; // Dimming level (0-128) 0 = on, 128 = 0ff int inc = 1; // counting up or down, 1=up, -1=down int freqStep = 75; // This is the delay-per-brightness step in microseconds. void setup() { lcd.begin(16, 2); lcd.createChar(0, thermometer); lcd.createChar(1, arrow); lcd.setCursor(0, 0); lcd.print("STATIE DE LIPIT"); myPID.SetMode(AUTOMATIC); myPID.SetOutputLimits(0, 128); pinMode(relay, OUTPUT); pinMode(potentiometer, INPUT); pinMode(zerocrossing, INPUT_PULLUP); pinMode(triac, OUTPUT); // Set the Triac pin as output delay(1200); lcd.clear(); // digitalWrite(triac, LOW); digitalWrite(relay, HIGH); attachInterrupt(digitalPinToInterrupt(2), zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need Timer1.attachInterrupt(dim_check, freqStep); } void zero_cross_detect() { zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured i = 0; digitalWrite(triac, LOW); // turn off TRIAC (and AC) } // Turn on the TRIAC at the appropriate time void dim_check() { if (zero_cross == true) { if (i >= dim) { digitalWrite(triac, HIGH); // turn on light i = 0; // reset time step counter zero_cross = false; //reset zero cross detection } else { i++; // increment time step counter } } } void loop() { //delay(18); pottemperature = analogRead(potentiometer); Setpoint = map(pottemperature, 0, 1023, 150, 400); //pottemperature is volatile realTemperature = thermocouple.readCelsius(); Input = int(0.779828 * realTemperature - 10.3427); // make temperature an integer if (isnan(realTemperature) || Input >= 432) { while (true) { displayErrors(); } } else { updateDisplay(); } double gap = abs(Setpoint - Input); //distance away from setpoint if (gap < 10) { myPID.SetTunings(consKp, consKi, consKd); } else { myPID.SetTunings(aggKp, aggKi, aggKd); } myPID.Compute(); dim = map(Output, 0, 128, 128, 0); delay(300); } void updateDisplay() { lcd.clear(); lcd.setCursor(0, 0); lcd.write((byte)0); lcd.setCursor(2, 0); lcd.print((int)Setpoint); lcd.setCursor(6, 0); lcd.print((char)223); //degree sign lcd.setCursor(7, 0); lcd.print("C"); lcd.setCursor(0, 1); lcd.write((byte)1); if (Input <= 45) { lcd.setCursor(2, 1); lcd.print("Lo"); } else { lcd.setCursor(2, 1); lcd.print((int)Input); } lcd.setCursor(6, 1); lcd.print("["); lcd.setCursor(7, 1); lcd.print((int)realTemperature); lcd.setCursor(10, 1); lcd.print("]"); lcd.setCursor(12, 1); lcd.print((char)223); lcd.setCursor(13, 1); lcd.print("C"); } void displayErrors() { digitalWrite(relay, LOW); lcd.clear(); lcd.setCursor(0, 0); lcd.write((byte)0); lcd.setCursor(1, 0); lcd.write((byte)0); lcd.setCursor(5, 0); lcd.print("ERROR!"); lcd.setCursor(14, 0); lcd.write((byte)0); lcd.setCursor(15, 0); lcd.write((byte)0); delay(300); }
  18. Voi adăgura și un cod nou testat, și adaug pentru început câteva capturi de ecran de pe osciloscop. Urmează și testul de stres propus de @roadrunner dar mai întâi vă aștept părerile legate de cod și capturi de ecran. PS: Pe capturile pe care se vede numai trasa albastră este forma de undă de pe rezistența letconului, iar pe celelalte capturi de ecran, forma de undă galbenă este semnalul de pe pinul 2 al lui Arduino, iar forma de undă albastră este semnalul de pe pinul 7 (output) al lui Arduino. PS2: Am făcut și testul de stres, temperatura a fost reglată la 320 C, am topit cositor de 1 mm grosime pe o bucată de PCB de 1.6 mm grosime, 55 mm lungime și 30 mm lățime si cu grosimea stratului de cupru de 35 um, iar în acest timp de 1-2 minute, temperatura a scăzut la 315 C iar apoi a început să crească inapoi la 320 C.
  19. Mulțumesc ! Am modificat codul, cu siguranță se mai poate îmbunătăți, dar vreau sa întreb cum pot să fac astfel încât bucla loop() să primească parametrii PID și apoi să calculeze valoarea PID iar apoi în aceeași buclă loop() să se și apeleze funcția de afișare ? A doua întrebare este cum pot să verific dacă am scris corect funcția zero() ? #include <LiquidCrystal.h> #include <SPI.h> #include <Wire.h> #include <max6675.h> #define thermoDO 12 #define thermoCS 10 #define thermoCLK 13 #define potentiometer A0 #define zerocrossing 2 #define triac 7 #define relay A1 volatile float temperature, realTemperature; // I have declared those 2 variables as VOLATILE, because of using them inside and outside ISR int pottemperature; int counter; int duty = 0; // variable for duty cycle byte thermometer[8] = //icon for termometer { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 }; byte arrow[8] = //icon for arrow { B11000, B01100, B00110, B00011, B00011, B00110, B01100, B11000 }; MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); /* The circuit: LCD RS pin to digital pin 12 LCD Enable pin to digital pin 11 LCD D4 pin to digital pin 5 LCD D5 pin to digital pin 4 LCD D6 pin to digital pin 3 LCD D7 pin to digital pin 2 LCD R/W pin to ground LCD VSS pin to ground LCD VCC pin to 5V 10K resistor: ends to +5V and ground wiper to LCD VO pin (pin 3) */ volatile int pidOut = 0; double sensed_output, control_signal; double setPoint; double Kp; //proportional gain double Ki; //integral gain double Kd; //derivative gain int T = 100; //sample time in milliseconds (ms) unsigned long last_time = 0; double total_error, last_error; int max_control = 0; int min_control = 240; LiquidCrystal lcd(3, 4, 5, 6, 8, 9); void setup() { lcd.createChar(0, thermometer); lcd.createChar(1, arrow); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("STATIE DE LIPIT"); delay(1200); lcd.clear(); pinMode(relay, OUTPUT); pinMode(potentiometer, INPUT); pinMode(zerocrossing, INPUT_PULLUP); pinMode(triac, OUTPUT); digitalWrite(triac, LOW); digitalWrite(relay, HIGH); realTemperature = thermocouple.readCelsius(); temperature = 0.779828 * realTemperature - 10.3427; //updateDisplay(); attachInterrupt(digitalPinToInterrupt(2), zero_crosss_int, RISING); } void loop() { //moved the PID computations outside the ISR unsigned long current_time = millis(); //returns the number of milliseconds passed since the Arduino started running the program int delta_time = current_time - last_time; //delta time interval pottemperature = analogRead(potentiometer); pottemperature = map(pottemperature, 0, 1023, 150, 400); setPoint = pottemperature; realTemperature = thermocouple.readCelsius(); temperature = int(0.779828 * realTemperature - 10.3427); // make temperature an integer sensed_output = temperature; if (isnan(realTemperature) || sensed_output >= 432) { while (true) { digitalWrite(relay, LOW); displayErrors(); } } else { updateDisplay(); } if (delta_time >= T) { double error = setPoint - sensed_output; if (error <= 10) { Kp = 4, Ki = 0.2, Kd = 1; } if (error > 10) { Kp = 1, Ki = 0.05, Kd = 0.25; } total_error += error; //accumalates the error - integral term if (total_error >= max_control) total_error = max_control; else if (total_error <= min_control) total_error = min_control; double delta_error = error - last_error; //difference of error for derivative term control_signal = Kp * error + (Ki * T) * total_error + (Kd / T) * delta_error; //PID control compute if (control_signal >= max_control) control_signal = max_control; else if (control_signal <= min_control) control_signal = min_control; last_error = error; } noInterrupts(); pidOut = int(control_signal); interrupts(); last_time = current_time; delay(250); } void zero_crosss_int() { int powertime = (39 * (256 - pidOut)); delayMicroseconds(powertime); digitalWrite(triac, HIGH); delayMicroseconds(10); digitalWrite(triac, LOW); } void updateDisplay() { pottemperature = analogRead(potentiometer); pottemperature = map(pottemperature, 0, 1023, 150, 400); lcd.clear(); lcd.setCursor(0, 0); lcd.write((byte)0); lcd.setCursor(2, 0); lcd.print((int)pottemperature); lcd.setCursor(6, 0); lcd.print((char)223); //degree sign lcd.setCursor(7, 0); lcd.print("C"); lcd.setCursor(0, 1); lcd.write((byte)1); if (temperature <= 45) { lcd.setCursor(2, 1); lcd.print("Lo"); } else { lcd.setCursor(2, 1); lcd.print((int)temperature); } lcd.setCursor(6, 1); lcd.print("["); lcd.setCursor(7, 1); lcd.print((int)realTemperature); lcd.setCursor(10, 1); lcd.print("]"); lcd.setCursor(12, 1); lcd.print((char)223); lcd.setCursor(13, 1); lcd.print("C"); } void displayErrors() { digitalWrite(relay, LOW); // the relay will disconnect the power to the soldering iron heating element lcd.clear(); lcd.setCursor(0, 0); lcd.write((byte)0); lcd.setCursor(1, 0); lcd.write((byte)0); lcd.setCursor(5, 0); lcd.print("ERROR!"); lcd.setCursor(14, 0); lcd.write((byte)0); lcd.setCursor(15, 0); lcd.write((byte)0); delay(500); }
  20. Mulțumesc ! Codul e și-și. Eu știam numai de bucla loop() și setup() la Arduino. Acum am citit că defapt, folosește main(), dar e ascuns ... int main(void) { init(); setup(); for (;;) { loop(); } return 0; }
  21. Mi-am dorit de multă vreme să construiesc o stație de lipit care să folosească curentul alternativ ca și sursă de curent pentru alimentarea rezistenței letconului. Inițial am construit proiectul acesta: https://www.allaboutcircuits.com/projects/do-it-yourself-soldering-station-with-an-atmega8/?utm_source=eetech&utm_medium=eetech-social&utm_campaign=reposts-projects/ căruia i-am adăugat o protecție la supratemepratură. Apoi am realizat proiectul acesta: https://www.instructables.com/id/DIY-Arduino-Soldering-Station/ Cu ajutor la scrierea programului, am realizat proiectul din această schemă: Explicațiile pentru schemă sunt: SV3 - avem conectați doar pinii A2 și A3 (veți vedea în program pentru că sunt folosiți la testare), SV1 - aici avem conectat un modul cu MAX6675 și SV2 - aici am conectat un LCD 1602, pe care se va afișa conform cu programul: temperatura setată din potențiometrul R7, temperatura aproximată a vârfului și [temperatura] citită de către MAX6675. OK1 generează câte un impuls pentru fiecare trecere prin 0 a tensiunii alternative, K1 este un releu care oprește alimentarea rezistenței în momentul în care este depășită temperatura de 432 C sau atunci când este decuplat unul sau ambele fire de la termocuplu, partea de alimentare este formată din LM317 și L7805, iar elementul de forță este alcătuit din triacul BT138, care este controlat de pinul 7 al lui Arduino Nano V3. Pentru controlul temperaturii, am folosit un controller de tip PID, prin utilizarea în mediul Arduino IDE a librăriei <PID_v1.h>. La prima vedere, controlerul pare să funcționeze. Programul implementat este: #include <PID_v1.h> #include <LiquidCrystal.h> #include <SPI.h> #include <Wire.h> #include <max6675.h> #define thermoDO 12 #define thermoCS 10 #define thermoCLK 13 #define potentiometer A0 #define zerocrossing 2 #define triac 7 #define relay A1 #define test A2 #define test1 A3 int lowError = 0; //guessing for now. The bigger these values the smaller the deadband either side of 0 error that constitues a 50% duty cycle int highError = 220; float temperature, realTemperature; int pottemperature; int counter; int tempError = false; // global error flag int shownError = false; //flag to say error shown int duty = 0; // variable for duty cycle //PID constants //double Kp = 5; //double Ki = 0.25; //double Kd = 0; //Define the aggressive and conservative Tuning Parameters double aggKp = 4, aggKi = 0.2, aggKd = 1; double consKp = 1, consKi = 0.05, consKd = 0.25; //PID variables unsigned long currentTime, previousTime; double elapsedTime; double error; double lastError; double input, output, setPoint; double cumError, rateError; PID myPID(&input, &output, &setPoint, consKp, consKi, consKd, DIRECT); byte thermometer[8] = //icon for termometer { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 }; byte arrow[8] = //icon for arrow { B11000, B01100, B00110, B00011, B00011, B00110, B01100, B11000 }; MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); /* The circuit: LCD RS pin to digital pin 12 LCD Enable pin to digital pin 11 LCD D4 pin to digital pin 5 LCD D5 pin to digital pin 4 LCD D6 pin to digital pin 3 LCD D7 pin to digital pin 2 LCD R/W pin to ground LCD VSS pin to ground LCD VCC pin to 5V 10K resistor: ends to +5V and ground wiper to LCD VO pin (pin 3) */ LiquidCrystal lcd(3, 4, 5, 6, 8, 9); // added stuff to log temperatures on serial monitor // change loop time management from simple delay #define PRINTRATE 100 #define DISPLAYRATE 250 char textbuf[100]; //buffer for data to send unsigned long serialTime = millis(); //sending interval for data unsigned long displayTime = serialTime; //display interval for LCD int pt; //local store for pot and iron temperatures; int tmp; double err, cErr, rErr, op; int dty; void setup() { myPID.SetMode(AUTOMATIC); myPID.SetOutputLimits(0, 220); Serial.begin(115200); // or faster if your Arduino/PC can handle it... pinMode(test, OUTPUT); pinMode(test1, OUTPUT); lcd.createChar(0, thermometer); lcd.createChar(1, arrow); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("STATIE DE LIPIT"); output = 0; setPoint = 0; delay(1200); lcd.clear(); pinMode(relay, OUTPUT); pinMode(potentiometer, INPUT); pinMode(zerocrossing, INPUT_PULLUP); pinMode(triac, OUTPUT); digitalWrite(triac, LOW); digitalWrite(relay, HIGH); realTemperature = thermocouple.readCelsius(); temperature = 0.779828 * realTemperature - 10.3427; input = temperature; //updateDisplay(); attachInterrupt(digitalPinToInterrupt(2), zero, RISING); } void loop() { if (millis() > serialTime + PRINTRATE) { //send serial data every PRINTRATE mS noInterrupts(); // make sure our local copies are not corrupted while copying them over from ISR tmp = temperature; pt = pottemperature; err = error; cErr = cumError; rErr = rateError; op = output; dty = duty; interrupts(); sprintf(textbuf, "Time: %lu, Set: %4u, Temp: %4u", millis() / 100, pt, tmp); //format the print string Serial.print(textbuf); sprintf(textbuf, ", error: %.9g, cumErr: %.9g, rateErr: %.9g, output: %.9g, duty: %3u", err, cErr, rErr, op, dty); Serial.println(textbuf); //send to serial monitor, about 3mS @ 115200 serialTime += PRINTRATE; } if (millis() > displayTime + DISPLAYRATE) { //update display every DISPLAYRATE mS if (!tempError) { // if no error updateDisplay(); } else // do something on error { // eg show the word error on the display if (!shownError) { // we've not shown error yet, so show it displayErrors(); shownError = true; //set flag so don't show it again } } displayTime += DISPLAYRATE; } } void zero() { counter++; //*** change this line below if (counter > duty) { //reach duty cycle limit, unless duty was 25 in which case leave on until next duty calculated later digitalWrite(triac, LOW); } if (counter >= 25) { counter = 0; digitalWrite(test, HIGH); //this will generate a pulse on test pin (5) every 250mS to prove counter incrementing... pottemperature = analogRead(potentiometer); pottemperature = map(pottemperature, 0, 1023, 150, 400); setPoint = pottemperature; digitalWrite(test, LOW); // put test pin low realTemperature = thermocouple.readCelsius(); temperature = int(0.779828 * realTemperature - 10.3427); // make temperature an integer input = temperature; if (tempError || isnan(realTemperature) || temperature >= 432) { // on error kill power & set global error flag digitalWrite(relay, LOW); // turn off power to iron //*** add this line below just in case digitalWrite(triac, LOW); tempError = true; //set error flag. can only be unset outside ISR. Once set no further action taken till unset in main loop. } else { //reading valid //*** if (temperature < pottemperature) { //*** remove this line and allow errors to be both + and - digitalWrite(test1, HIGH); // *** changed, generate a pulse on test1 (D6) when reading valid //error = pottemperature - temperature; // *** +ve error when low = increase duty cycle, -ve error when high = decrease it double gap = abs(setPoint - input); //distance away from setpoint if (gap < 10) { //we're close to setpoint, use conservative tuning parameters myPID.SetTunings(consKp, consKi, consKd); } else { //we're far from setpoint, use aggressive tuning parameters myPID.SetTunings(aggKp, aggKi, aggKd); } myPID.Compute(); // error = map(error, lowError, highError, 0, 24); // cumError += error * 250.0; // // rateError = (error - lastError) / 250.0; // // output = Kp * error + Ki * cumError + Kd * rateError; //output error needs to be mapped to a number between 0 and 24 duty = map(output, lowError, highError, 0, 25); // *** lowError is const for fully off, highError is const for fully on. zero error maps to 50% duty = constrain(duty, 0, 25); // ***keep duty between 0 and 25 (25 = 100%) //*** re-arrange & add 3 lines if (duty > 0) { digitalWrite(triac, HIGH); } else { digitalWrite(triac, LOW); } lastError = error; digitalWrite(test1, LOW); //*** remove 3 lines // } // else { // duty = 0; // }//if (temperature }//if (tempError } //if(counter >= 25 }// zero() void updateDisplay() { pottemperature = analogRead(potentiometer); pottemperature = map(pottemperature, 0, 1023, 150, 400); lcd.clear(); lcd.setCursor(0, 0); lcd.write((byte)0); lcd.setCursor(2, 0); lcd.print((int)pottemperature); lcd.setCursor(6, 0); lcd.print((char)223); //degree sign lcd.setCursor(7, 0); lcd.print("C"); lcd.setCursor(0, 1); lcd.write((byte)1); if (temperature <= 45) { lcd.setCursor(2, 1); lcd.print("Lo"); } else { lcd.setCursor(2, 1); lcd.print((int)temperature); } lcd.setCursor(6, 1); lcd.print("["); lcd.setCursor(7, 1); lcd.print((int)realTemperature); lcd.setCursor(10, 1); lcd.print("]"); lcd.setCursor(12, 1); lcd.print((char)223); lcd.setCursor(13, 1); lcd.print("C"); } void displayErrors() { digitalWrite(relay, LOW); // the relay will disconnect the power to the soldering iron heating element lcd.clear(); lcd.setCursor(0, 0); lcd.write((byte)0); lcd.setCursor(1, 0); lcd.write((byte)0); lcd.setCursor(5, 0); lcd.print("ERROR!"); lcd.setCursor(14, 0); lcd.write((byte)0); lcd.setCursor(15, 0); lcd.write((byte)0); } Am 2 întrebări în ceea ce privește programul (codul) implementat: 1. Observ pe osciloscop că tranziția de la 0 logic la 1 logic (0V - 5V) de pe pinul 7 (albastru pe imagine) al lui Arduino, se face cu o întârziere de aproximativ 1 mS față de impulsul care il primește pe pinul 2 (galben pe imagine). În ce măsură afectează această întârziere funcționarea circuitului ? În timp ce tranziția de la 1 la 0 se face la momentul potrivit: Pe rezistența letconului: 2. Ce parere aveti despre cod ? Eu am adăugat numai partea cu implementarea PID-ului. Acesta este rezultatul (albastru = setpoint și roșu = temperatura letconului): Vă mulțumesc pentru eventualele sfaturi/observații/comentarii. 😀 Urmează și partea cu realizarea practică a stației, dar mai întâi aș dori să rezolv problemele prezentate. Dacă există informații neclare sau incomplete, vă rog să îmi spuneți și voi încerca să clarific.
  22. Am văzut că există pe internet la diverși vânzători de componente mai multe part number-uri de amplificatoare pentru termocupluri (InAmp), dar nu sunt încă lămurit dacă există posibilitatea de a construi un astfel de amplificator folosind unul/mai multe amplificatoare operaționale clasice - LM324, LM358 + alte componente. Mă interesează să amplific semnalul de la un termocuplu de tip K și apoi să îl citesc cu un Arduino și să îl prelucrez. Poate cineva să mă îndrume spre un material/materiale sau schemă/scheme cu astfel de amplificatoare ? Mulțumesc.
  23. Am realizat plăcuța și am conectat-o la display, la sursă și la letcon și e funcțională. Înainte de corodare, după imprimare și corecție: după corodare: după stanare: după găurire: plăcuța instalată în carcasă, pentru a verifica funcționalitatea:
  24. Prin metoda press & peel, dar în loc de hârtie specială, folosesc hârtie de la niște reclame, care a dat rezultate bune în trecut (înainte să apară problema la imprimantă).
  25. Am încercat să refac o porțiune din layout. Am mutat tranzistorul de putere din partea dreaptă în partea stângă iar bobina și condensatorul din partea stângă în partea dreaptă. La layout-ul vechi am găsit o problemă și anume faptul că conectorul USB de la Arduino venea direct peste condensatorul de 4700uF. Astfel am mutat condensatorul și acum e în regulă. Varianta aceasta de layout aș prefera să o construiesc, dacă e în regulă.
×
×
  • Creează nouă...

Informații Importante

Folosim cookie-uri și tehnologii asemănătoare pentru a-ți îmbunătăți experiența pe acest website, pentru a-ți oferi conținut și reclame personalizate și pentru a analiza traficul și audiența website-ului. Înainte de a continua navigarea pe www.tehnium-azi.ro te rugăm să fii de acord cu: Termeni de Utilizare.