GeoMar Postat Septembrie 1, 2013 Autor Partajează Postat Septembrie 1, 2013 Hello GeoMarI wonder if it's possible to change the software to disconnect the power IMMEDIATELY in case of short circuit?Even .1 second is too much! because the power transistors burn so fast when the output Probes gets shorted.Thank you so much.CiroTry this version, I tested in ISIS, not actually in assembly.[attachment=0]Volt Amper Termo cu 16F877A kooroshi60 v1.0.rar[/attachment] Link spre comentariu
danpin Postat Septembrie 27, 2013 Partajează Postat Septembrie 27, 2013 Salutari,Inspirandu-ma dupa modelul softului facut de dl. GeoMar si din ce am mai gasit pe forum am incercat sa fac si eu ceva similar. In softul atasat, daca scot, comentez (//) oricare dintre functiile "show_intro()" sau "ShowTemp ()" pare ca functioneaza atunci cand il simulez in Isis dar cu amandoua functiile nu afiseaza nimic.Daca este cineva dispus sa-mi dea o mana de ajutor...multumesc anticipat! Link spre comentariu
kinderu56 Postat Octombrie 14, 2013 Partajează Postat Octombrie 14, 2013 salut a mai inbunatatit cineva acest soft ? daca nu poate putem sa facem modificarea asta deca este din soft ,este ok sa varieze consumul pe un bec de 21W/12V intre 20w si27W si amperajul consumat le fel ?? si cu orice fel de consumator face la fel ,la 3 leduri de 1W legate in serie variaza intre 290ma si 350ma iar pe aparat imi arata fix 300ma fara sa fluctueze, si inca o chestie ar fi daca se poate mari plaja de on/off a ventilatorului, ceva de genu ,38 grade ON si 30 grade OFF chestia este ca acuma diferenta de ON/OFF este de un grad si daca lucrezi o zi intreaga, mai ales seara (cand mai doarme lumea si daca ai un ventilatorde 12V1.5A cam face galagie , si ultima ar fi sa nu mai clipeaca lcd-ul pe indicatia de temp si pe cea de wati ,am abservat ca atunci cand clipeste se schimba si indicatia pe consum in amperi si pe cea de watii atunci se vede fluctuatia .multumesc Link spre comentariu
nooob64 Postat Octombrie 16, 2013 Partajează Postat Octombrie 16, 2013 Va aparea cit de curind sper un V-A metru(0-30V 0-5A) cu PIC, afisaj 7 segmente (2 x 3digiti), autoscalare si tot felu de setari customizabile printr-un singur buton. Link spre comentariu
kinderu56 Postat Octombrie 16, 2013 Partajează Postat Octombrie 16, 2013 pentru mine aceasta este suficienta pentru ia as fi interesat de inbunatatiri la softt Link spre comentariu
adicontakt Postat Octombrie 16, 2013 Partajează Postat Octombrie 16, 2013 Va aparea cit de curind sper un V-A metru(0-30V 0-5A) cu PIC, afisaj 7 segmente (2 x 3digiti), autoscalare si tot felu de setari customizabile printr-un singur buton.cat de curand? chiar sunt curios cum arata Link spre comentariu
nooob64 Postat Octombrie 16, 2013 Partajează Postat Octombrie 16, 2013 Nu stiu inca ... mai am de proiectat partea hardware, apoi vine softul. Controlul display are deja la baza un max7219, iar daca toate merg bine va devenii subiect la bazar.Atasez schema prototipului. Link spre comentariu
nooob64 Postat Octombrie 16, 2013 Partajează Postat Octombrie 16, 2013 Am si gasit o problema, in loc sa leg la masa rezistenta lui INA138 am legat-o in serie cu operationalul Link spre comentariu
danpin Postat Octombrie 20, 2013 Partajează Postat Octombrie 20, 2013 Salut,kinderu56Imi amintesc ca atunci cind mi-am facut V/A-metrul am testat si hex-ul personalizat pt. tine de GeoMar, nu am avut probleme cu fluctuatia indicatiei pt. curent. Doar indicatia temperaturii avea un flicker.Incearca sa scrii in PIC alt software din cele facute de GeoMar si vezi daca problema se mentine...Ultimele probe le-am facut cu hex-ul "Volt Amper Termo cu 16F877A_GeoMar_v2.2_by_The_Reaper", cu becuri auto legate in serie, paralel, pt a simula diverse sarcini pe sursa, iar indicatia pe curent/putere tot timpul a fost stabila si coincidea destul de bine cu indicatia multimetrului.Poate alimentarea V/A-metrului nu e tocmai OK si iti variaza tensiunea pe pinul RA3/AN3/VREF+ sau ceva pe la cablaj, fire de semnal mic ce trec pe linga transformator sau pe linga alimentarea de 220v.Pt. ventilator trebuie facuta o modificare in soft.Eu incerc sa-mi fac un soft (invat din mers, sunt incepator), am experimentat doar in simulator, am sursa si V/A-ul desfacute si nu pot sa testez direct pe PIC, lucrez la carcasa sursei si pina nu o termin nu ma apuc iar de intins fire ...Daca vrei sa experimentezi iti dau hex-ul sa-l probezi...Salutari! Link spre comentariu
danpin Postat Octombrie 27, 2013 Partajează Postat Octombrie 27, 2013 Salutari! Am ajuns spre final cu programul pt. VA-metru. L-am testat in simulator dar nu inca in PIC. In simulator pare ca functioneaza…. Functionarea este similara cu a celui facut de GeoMar. Ar trebui sa faca urmatoarele si in PIC…sper… Afiseaza tensiune, curent, putere si temperatura radiatorului sursei de alimentare. La scurtcircuit pe iesire: declanseaza releul si afiseaza mesaj + beep (intermitent). Pt. resetare trebuie adusa tensiunea la 0 din potentiometrul sursei. La supracurent: declanseaza releul si afiseaza mesaj + beep (intermitent). Pt. resetare trebuie adusa tensiunea la 0 din potentiometrul sursei. La supratemperatura: T >90 grade C: declanseaza releul si afiseaza mesaj + beep (intermitent) + afisare temperatura (constant). Ventilatorul porneste la 40 grade C si se opreste la 30 grade C. Ventilatorul trebuie sa functioneze si in caz de scurtcircuit sau supracurent (atunci cand este activa subrutina respectiva). Am incercat un timing pt. beep-uri, adica in primul minut (sau minute) sa beep-aie mai des si dupa expirarea timpului ceva mai rar, sa zicem o data pe minut. Inca mai trebuie sa setez timpii, probabil experimental cind il voi testa in PIC sau daca invat intre timp cum pot sa vad timpii in simulare…. Nu am reusit sa fac stabila afisarea temperaturilor negative, le afiseaza dar are un flicker. Pt. simulare am folosit DS18B20, pt. al tip de DS trebuie schimbata rezolutia. In functie de buzzer-ul folosit posibil sa trebuiasca facute ceva modificari la sound. Daca cineva are idei pt. optimizarea programului, orice sfat este bine primit. Programul l-am facut ca sa invat un pic de programare, din cauza asta e asa "stufos". Toate bune! // LCD module connectionssbit LCD_RS at RB2_bit;sbit LCD_EN at RB3_bit;sbit LCD_D4 at RB4_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D7 at RB7_bit;sbit LCD_RS_Direction at TRISB2_bit;sbit LCD_EN_Direction at TRISB3_bit;sbit LCD_D4_Direction at TRISB4_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D7_Direction at TRISB7_bit;// End LCD module connectionschar msg[17]; //declare array set to max size required plus 1 [for terminator] for copying into// copy const to ram stringchar * CopyConst2Ram(char * dest, const char * src){ char * d ; d = dest; for(;*dest++ = *src++;) ; return d;}const char LCD_txt1[] = "Hello friend!";const char LCD_txt2[] = "How are you?";const char LCD_txt3[] = "Loading modules";const char LCD_txt4[] = "Power supply";const char LCD_txt5[] = "0-30Vdc 0-10Adc";const char LCD_txt6[] = "* I'm ready! *";const char LCD_txt7[] = "What about you?";const char LCD_txt8[] = "Output short";const char LCD_txt9[] = "circuit detected";const char LCD_txt10[] = "Please remove";const char LCD_txt11[] = "short circuit!";const char LCD_txt12[] = "OVERCURRENT";const char LCD_txt13[] = "I > 10A";const char LCD_txt14[] = "Overtemperature!";const char LCD_txt15[] = "T>90";const char units[] = {'V', 'A', 'W'}; void Tone1() { Sound_Play(659, 75); // Frequency = 659Hz, duration = 250ms}void Tone2() { Sound_Play(698, 75); // Frequency = 698Hz, duration = 250ms}void Tone3() { Sound_Play(784, 75); // Frequency = 784Hz, duration = 250ms}bit x; // Flag for subroutine short or overcurrentunsigned int y=0, time=0, scov=0, tmp=0, sc=0;void interrupt() { if (INTCON.TMR0IF ==1) { sc++; // Used in short-circuit timing tmp++; // Used in read temperature timing scov++; // Used in short-circuit, overcurrent and overtemperature timing time++; // Used in read temperature timing y++; // Used in short-circuit, overcurrent and overtemperature timing INTCON.TMR0IF = 0; // Clear timer0 interrupt flag TMR0 = 4; // Preset for timer register } }const char character[] = {14,10,14,4,31,4,10,17}; // Initial splash screen symbolvoid CustomChar(char pos_row, char pos_char){ char i; Lcd_Cmd(64); for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]); Lcd_Cmd(_LCD_RETURN_HOME); Lcd_Chr(pos_row, pos_char, 0);}unsigned char ch, ADCx;unsigned int Voltage, Current;unsigned long V, A, Pw; void show_intro(void) // Initial splash screen{ char i;Tone1(); delay_ms (100); Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off Lcd_Cmd(_LCD_CLEAR); // Clear LCD Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt1)); // Write text "Hello friend!" in first row delay_ms (1000);Tone1(); Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt2)); // Write text "How are you?" in second row delay_ms (1500); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,2,CopyConst2Ram(msg,LCD_txt3)); // Write text "Loading modules" in first row delay_ms(200); CustomChar (2,1); // Write custom character in second row --> for(i=0;i<15;i++) { LCD_Chr_CP(0); Tone3(); delay_ms(50); } delay_ms(200); CustomChar (2,0); // Delete custom character in second row --> for(i=16;i>0;--i) { Tone2(); LCD_Chr_CP(32); delay_ms(50); } delay_ms(500); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR);Tone1(); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt4)); // Write text "Power supply" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt5)); // Write text "0-30Vdc 0-10Adc" in second row delay_ms(2500); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,2,CopyConst2Ram(msg,LCD_txt6)); // Write text "* I'm ready! *" in first row Lcd_Out(2,2,CopyConst2Ram(msg,LCD_txt7)); // Write text "What about you?" in second rowTone1();Tone2();Tone3();Tone3();Tone1();Tone2();Tone3();Tone3();Tone1(); Tone2(); Tone3(); delay_ms(1500); Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off Lcd_Cmd(_LCD_CLEAR); // Clear LCD}const unsigned short TEMP_RESOLUTION = 12; // Resolution of used DS18x20 sensorchar *text = " 0.00";unsigned temp; void Display_Temperature(int temp2write) // Format temperature results { bit T; // Flag to select negative or positive temperature display const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8; char temp_whole; unsigned int temp_fraction; // Check if temperature is negative if (temp2write & 0x8000) { T=1; // Flag =1 to select negative temperature display temp2write = ~temp2write + 1; } else T=0; // Flag =0 to select positive temperature display // Extract temp_whole temp_whole = temp2write >> RES_SHIFT ; // Convet temp_whole to characters switch(T) { case 0: // Display if temperature is positive if(!(temp_whole/100)) text[0] = ' '; else text[0] = temp_whole/100 + 48; // Extract hundreds digit if(!(temp_whole/10)%10) text[1] = ' '; else text[1] = (temp_whole/10)%10 + 48; // Extract tens digit text[2] = temp_whole%10 + 48; // Extract ones digit break; case 1: // Display if temperature is negative if(!((temp_whole/10)%10)) { text[0] = ' '; text[1] = '-'; text[2] = (temp_whole%10 + 48); // Extract ones digit } if((temp_whole/10)%10) { text[0] = '-'; text[1] = ((temp_whole/10)%10 + 48); // Extract tens digit text[2] = (temp_whole%10 + 48); // Extract ones digit } break; } // Extract temp_fraction and convert it to unsigned int temp_fraction = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625; // Convert temp_fraction to characters text[4] = temp_fraction/1000 + 48; // Extract thousands digit text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit /* if(T==1) ( test cu if-uri pt. afisaj temperatura) { if((temp_whole/10)%10) { text[0] = ('-'); text[1] = (temp_whole/10)%10 + 48; // Extract tens digit text[2] = temp_whole%10 + 48; // Extract ones digit } else { text[0] = (' '); text[1] = ('-'); text[2] = temp_whole%10 + 48; // Extract ones digit } T=0; } else // if (temp_whole/100) { if(!(temp_whole/100)) //&& (temp2write & 0x8000)) text[0] = ' '; if(temp_whole/100) text[0] = temp_whole/100 + 48; if(!(temp_whole/10)%10) text[1] = ' '; else text[1] = (temp_whole/10)%10 + 48; // Extract tens digit text[2] = temp_whole%10 + 48; // Extract ones digit // Extract temp_fraction and convert it to unsigned int temp_fraction = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625; // Convert temp_fraction to characters text[4] = temp_fraction/1000 + 48; // Extract thousands digit text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit } */ } void ReadTemp() // Perform temperature reading { Ow_Reset(&PORTD, 0); // Onewire reset signal Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM Ow_Write(&PORTD, 0, 0x44); // Issue command CONVERT_T if (time>50) // Delay for temp conversion (Temperature Conversion Time 750ms Max) { Ow_Reset(&PORTD, 0); Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM Ow_Write(&PORTD, 0, 0xBE); // Issue command READ_SCRATCHPAD temp = Ow_Read(&PORTD, 0); temp = (Ow_Read(&PORTD, 0) << 8) + temp; time=0; } } const char gradc[] = {16,6,9,8,8,9,6,0}; // Degree celsius symbol void celsius(char pos_row, char pos_char) { char i; Lcd_Cmd(64); for (i = 0; i<=7; i++) Lcd_Chr_CP(gradc[i]); Lcd_Cmd(_LCD_RETURN_HOME); Lcd_Chr(pos_row, pos_char, 0); } void Display_Temp() // Display Temperature { Lcd_Out(2,10,text); Display_Temperature(temp); ReadTemp(); } void Overtemp() // Overtemperature subroutine{ if(!(temp & 0x8000)) { scov=0; y=0; Lcd_Cmd(_LCD_CLEAR); PORTB.F1=0; // Relay OFF while (temp>1280) { celsius(2,16); // Degree celsius symbol Display_Temp(); // Display temperature if(scov<1500) { if(y>10) { Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt14)); // Write text "Overtemperature!" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt15)); // Write text "T>90" in second row celsius(2,5); // Write celsius symbol after "T>90" in second row } if(y>150) { Tone3(); Lcd_Cmd(_LCD_CLEAR); y=0; } } if(scov>1550) { if(y>10) { Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt14)); // Write text "Overtemperature!" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt15)); // Write text "T>90" in second row celsius(2,5); // Write celsius symbol after "T>90" in second row } if(y>1000) { Tone3(); Lcd_Cmd(_LCD_CLEAR); y=0; scov=1551 ; } } } } Lcd_Cmd(_LCD_CLEAR);} void volt_ADC() // Reading the analog inputs (ADC) { Voltage = 0; for (ADCx=0; ADCx<10; ADCx++) { Voltage += ADC_Read(1); // Reading voltage values from channel 1 Delay_us(50); } Voltage = Voltage/ADCx; // Voltage calculation V = (long)Voltage*3500; // Millivolts conversion V = V/1023; // 0...1023 => 0...3500mV } void crt_ADC() // Reading the analog inputs (ADC) { Current = 0; for (ADCx=0; ADCx<10; ADCx++) { Current += ADC_Read(0); // Reading current values from channel 0 Delay_us(50); } Current = Current/ADCx; // Current calculation A = (long)Current*3500; // Millivolts conversion A = A/1023; // 0..1023 => 0...3500mV } void Display_voltage () { ch = V/1000; // Extract tens digit 10.00 if (ch==0) Lcd_Chr(1,1,32); else Lcd_Chr(1,1,48+ch); // Display results in ASCII format ch = (V/100) % 10; // Extract ones digit 01.00 Lcd_Chr_CP(48+ch); // Display results in ASCII format Lcd_Chr_CP('.'); // Display caracter '.' ch = (V/10) % 10; // Extract tenths digit 00.10 Lcd_Chr_CP(48+ch); ch = V % 10; // Extract hundredths digit 00.01 Lcd_Chr_CP(48+ch); LCD_Chr_CP (units[0]); // Print "V" after voltage value Delay_us(10); } void Display_current () { ch = A/1000; // Extract tens 10.00 if (ch==0) Lcd_Chr(1,11,32); else Lcd_Chr(1,11,48+ch); // Display results in ASCII format ch = (A/100) % 10; // Extract ones digit 01.00 Lcd_Chr_CP(48+ch); // Display results in ASCII format Lcd_Chr_CP('.'); // Display caracter '.' ch = (A/10) %10; // Extract tenths 00.10 Lcd_Chr_CP(48+ch); // Display results in ASCII format ch = A % 10; // Extract hundredths 00.01 Lcd_Chr_CP(48+ch); Lcd_Chr_CP(units[1]); // Print "A" after current value Delay_us(10); // Ten microseconds delay } void Display_power () { Pw = V*A/1000; // Power calculation ch = Pw/1000; // Hundreds digit calculation and display if (ch==0) Lcd_Chr(2,1,32); else Lcd_Chr(2,1,48+ch); ch = (Pw/100) % 10; // Tens digit calculation and display if (ch==0 && (Pw/1000==0)) Lcd_Chr(2,2,32); else Lcd_Chr(2,2,48+ch); ch = (Pw/10) %10; // Units digit calculation and display Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); // Display caracter '.' ch = (Pw/1) % 10; // Tenths digit calculation and display Lcd_Chr_CP(48+ch); Lcd_Chr_CP(units[2]); // Print "W" after power value } void display_short() // Short circuit subroutine { char a; PORTB.F1=0; // Relay OFF Lcd_Cmd(_LCD_CLEAR); y=0; scov=0; sc=0; do { if(sc<1500) a=1; if(sc>1500) a=2; switch(a) { case 1: if(y<10) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt8)); // Write text "Output short" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt9)); // Write text "circuit detected" in second row Tone3(); Tone1(); scov=0; y=50; } if((y>150)&&(scov<250)) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt10)); // Write text "Please remove" in first row Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt11)); // Write text "short circuit!" in second row Tone1(); Tone3(); scov=250; } if(scov>350) { y=0; } break; case 2: if(y<10) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt8)); // Write text "Output short" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt9)); // Write text "circuit detected" in second row Tone3(); Tone1(); scov=0; y=50; } if((y>1000)&&(scov<1650)) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt10)); // Write text "Please remove" in first row Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt11)); // Write text "short circuit!" in second row Tone1(); Tone3(); scov=1650; } if(scov>2300) { y=0; } break; } if(tmp>50) // Delay for temp conversion (Temperature Conversion Time 750ms Max) { ReadTemp(); tmp=0; } if((temp>625)&&(!(temp & 0x8000))) PORTD.F1=1; // If temp. is positive and > 40 start cooler if(temp<480) PORTD.F1=0; // If temp is < 30 stop cooler volt_ADC(); // Read voltage } while(V>0); // Do print_scurt while voltage > 0 Lcd_Cmd(_LCD_CLEAR); x=1; // Set flag x} void display_overcurrent() // Overcurrent subroutine { PORTB.F1=0; // Relay OFF Lcd_Cmd(_LCD_CLEAR); scov=0; y=0; //PORTB.F0=1; do { if(scov<1500) { if(y>10) { Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt12)); // Write text "OVERCURRENT" in first row Lcd_Out(2,5,CopyConst2Ram(msg,LCD_txt13)); // Write text "I > 10A" in second row } if(y>150) { Tone2(); Lcd_Cmd(_LCD_CLEAR); y=0; } } else //if(scov>=1550) { if(y>5) { Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt12)); // Write text "OVERCURRENT" in first row Lcd_Out(2,5,CopyConst2Ram(msg,LCD_txt13)); // Write text "I > 10A" in second row } if(y>1000) { Tone2(); Lcd_Cmd(_LCD_CLEAR); y=0; } scov=1500 ; } if(tmp>50) // Delay for temp conversion (Temperature Conversion Time 750ms Max) { ReadTemp(); tmp=0; } if((temp>625)&&(!(temp & 0x8000))) PORTD.F1=1; // If temp.is positive and > 40 start cooler if(temp<480) PORTD.F1=0; // If temp is < 30 stop cooler volt_ADC(); // Read voltage } while(V>0); // Do print_overload while voltage > 0 Lcd_Cmd(_LCD_CLEAR); x=1; // Set flag x } void main(){ TRISB=0; // Make PORTB pin an output PORTB=0; // Set PORTB to 0 ADCON1 = 0x88; // Configure Vref, and analog channels TRISA = 0xFF; // Designate PORTA as input TRISD = 0xFD; // Designate PORTD as input, RD1 output OPTION_REG = 0; // Clear option register OPTION_REG = 0b10000111; // Prescaler is assigned to the Timer0, Prescaler = 256 INTCON = 0; // Clear the interrpt control register INTCON = 0b10100000; // Bit7 global interrupt enable, Bit5 TMR0 overflow interrupt enable TMR0 = 4; // Preset for timer register PORTD.F1=0; // Set PORTD pin 1 to 0 //PORTB.F1=0; // Set PORTB pin 1 to 0 Sound_Init(&PORTB, 0); // Configures the MCU pin 0 for sound generation Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off show_intro(); // Show splash screen Lcd_Cmd(_LCD_CLEAR); Delay_ms(10); // 10 milliseconds delay time=0; while(1) // Endless loop { do { volt_ADC(); // Read voltage crt_ADC(); // Read current x=0; // Reset flag x if((V==0) && (A>0)) display_short(); // Check for output short circuit if((V>0) && (A>1000)) display_overcurrent(); // Check for output overcurrent } while(x>0); // Do while x=1, means that the subroutine short or overcurrent has finished PORTB.F1=1; // Relay ON PORTB.F0=0; // Set PORTB pin 0 to 0 celsius(2,16); // Display degree celsius symbol row 2 col 16 Display_voltage(); Display_current(); Display_power(); Display_Temp(); if((temp>625)&&(!(temp & 0x8000))) PORTD.F1=1; // If temp.is positive and > 40 start cooler if(temp<480) PORTD.F1=0; // If temp is < 30 stop cooler if(temp>1450) Overtemp(); // If temp is > 90 do overtemp }} Link spre comentariu
Vizitator sergiu 4wd Postat Martie 2, 2014 Partajează Postat Martie 2, 2014 Salutare, Sunt nou pe acest forum si vreau sa va adresez si eu o intrebare .Pot atasa un Voltmetru/Ampermetru cu PIC 16F877A unei surse in comutatie de PC ? Link spre comentariu
Vizitator kooroshi60 Postat Noiembrie 7, 2014 Partajează Postat Noiembrie 7, 2014 Salutari!Am ajuns spre final cu programul pt. VA-metru.L-am testat in simulator dar nu inca in PIC. In simulator pare ca functioneaza….Functionarea este similara cu a celui facut de GeoMar.Ar trebui sa faca urmatoarele si in PIC…sper…Afiseaza tensiune, curent, putere si temperatura radiatorului sursei de alimentare.La scurtcircuit pe iesire: declanseaza releul si afiseaza mesaj + beep (intermitent).Pt. resetare trebuie adusa tensiunea la 0 din potentiometrul sursei.La supracurent: declanseaza releul si afiseaza mesaj + beep (intermitent).Pt. resetare trebuie adusa tensiunea la 0 din potentiometrul sursei.La supratemperatura: T >90 grade C: declanseaza releul si afiseaza mesaj + beep (intermitent) + afisare temperatura (constant).Ventilatorul porneste la 40 grade C si se opreste la 30 grade C.Ventilatorul trebuie sa functioneze si in caz de scurtcircuit sau supracurent (atunci cand este activa subrutina respectiva).Am incercat un timing pt. beep-uri, adica in primul minut (sau minute) sa beep-aie mai des si dupa expirarea timpului ceva mai rar, sa zicem o data pe minut. Inca mai trebuie sa setez timpii, probabil experimental cind il voi testa in PIC sau daca invat intre timp cum pot sa vad timpii in simulare….Nu am reusit sa fac stabila afisarea temperaturilor negative, le afiseaza dar are un flicker.Pt. simulare am folosit DS18B20, pt. al tip de DS trebuie schimbata rezolutia.In functie de buzzer-ul folosit posibil sa trebuiasca facute ceva modificari la sound.Daca cineva are idei pt. optimizarea programului, orice sfat este bine primit.Programul l-am facut ca sa invat un pic de programare, din cauza asta e asa "stufos".Toate bune! // LCD module connectionssbit LCD_RS at RB2_bit;sbit LCD_EN at RB3_bit;sbit LCD_D4 at RB4_bit;sbit LCD_D5 at RB5_bit;sbit LCD_D6 at RB6_bit;sbit LCD_D7 at RB7_bit;sbit LCD_RS_Direction at TRISB2_bit;sbit LCD_EN_Direction at TRISB3_bit;sbit LCD_D4_Direction at TRISB4_bit;sbit LCD_D5_Direction at TRISB5_bit;sbit LCD_D6_Direction at TRISB6_bit;sbit LCD_D7_Direction at TRISB7_bit;// End LCD module connectionschar msg[17]; //declare array set to max size required plus 1 [for terminator] for copying into// copy const to ram stringchar * CopyConst2Ram(char * dest, const char * src){ char * d ; d = dest; for(;*dest++ = *src++;) ; return d;}const char LCD_txt1[] = "Hello friend!";const char LCD_txt2[] = "How are you?";const char LCD_txt3[] = "Loading modules";const char LCD_txt4[] = "Power supply";const char LCD_txt5[] = "0-30Vdc 0-10Adc";const char LCD_txt6[] = "* I'm ready! *";const char LCD_txt7[] = "What about you?";const char LCD_txt8[] = "Output short";const char LCD_txt9[] = "circuit detected";const char LCD_txt10[] = "Please remove";const char LCD_txt11[] = "short circuit!";const char LCD_txt12[] = "OVERCURRENT";const char LCD_txt13[] = "I > 10A";const char LCD_txt14[] = "Overtemperature!";const char LCD_txt15[] = "T>90";const char units[] = {'V', 'A', 'W'}; void Tone1() { Sound_Play(659, 75); // Frequency = 659Hz, duration = 250ms}void Tone2() { Sound_Play(698, 75); // Frequency = 698Hz, duration = 250ms}void Tone3() { Sound_Play(784, 75); // Frequency = 784Hz, duration = 250ms}bit x; // Flag for subroutine short or overcurrentunsigned int y=0, time=0, scov=0, tmp=0, sc=0;void interrupt() { if (INTCON.TMR0IF ==1) { sc++; // Used in short-circuit timing tmp++; // Used in read temperature timing scov++; // Used in short-circuit, overcurrent and overtemperature timing time++; // Used in read temperature timing y++; // Used in short-circuit, overcurrent and overtemperature timing INTCON.TMR0IF = 0; // Clear timer0 interrupt flag TMR0 = 4; // Preset for timer register } }const char character[] = {14,10,14,4,31,4,10,17}; // Initial splash screen symbolvoid CustomChar(char pos_row, char pos_char){ char i; Lcd_Cmd(64); for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]); Lcd_Cmd(_LCD_RETURN_HOME); Lcd_Chr(pos_row, pos_char, 0);}unsigned char ch, ADCx;unsigned int Voltage, Current;unsigned long V, A, Pw; void show_intro(void) // Initial splash screen{ char i;Tone1(); delay_ms (100); Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off Lcd_Cmd(_LCD_CLEAR); // Clear LCD Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt1)); // Write text "Hello friend!" in first row delay_ms (1000);Tone1(); Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt2)); // Write text "How are you?" in second row delay_ms (1500); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,2,CopyConst2Ram(msg,LCD_txt3)); // Write text "Loading modules" in first row delay_ms(200); CustomChar (2,1); // Write custom character in second row --> for(i=0;i<15;i++) { LCD_Chr_CP(0); Tone3(); delay_ms(50); } delay_ms(200); CustomChar (2,0); // Delete custom character in second row --> for(i=16;i>0;--i) { Tone2(); LCD_Chr_CP(32); delay_ms(50); } delay_ms(500); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR);Tone1(); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt4)); // Write text "Power supply" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt5)); // Write text "0-30Vdc 0-10Adc" in second row delay_ms(2500); Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,2,CopyConst2Ram(msg,LCD_txt6)); // Write text "* I'm ready! *" in first row Lcd_Out(2,2,CopyConst2Ram(msg,LCD_txt7)); // Write text "What about you?" in second rowTone1();Tone2();Tone3();Tone3();Tone1();Tone2();Tone3();Tone3();Tone1(); Tone2(); Tone3(); delay_ms(1500); Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off Lcd_Cmd(_LCD_CLEAR); // Clear LCD}const unsigned short TEMP_RESOLUTION = 12; // Resolution of used DS18x20 sensorchar *text = " 0.00";unsigned temp; void Display_Temperature(int temp2write) // Format temperature results { bit T; // Flag to select negative or positive temperature display const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8; char temp_whole; unsigned int temp_fraction; // Check if temperature is negative if (temp2write & 0x8000) { T=1; // Flag =1 to select negative temperature display temp2write = ~temp2write + 1; } else T=0; // Flag =0 to select positive temperature display // Extract temp_whole temp_whole = temp2write >> RES_SHIFT ; // Convet temp_whole to characters switch(T) { case 0: // Display if temperature is positive if(!(temp_whole/100)) text[0] = ' '; else text[0] = temp_whole/100 + 48; // Extract hundreds digit if(!(temp_whole/10)%10) text[1] = ' '; else text[1] = (temp_whole/10)%10 + 48; // Extract tens digit text[2] = temp_whole%10 + 48; // Extract ones digit break; case 1: // Display if temperature is negative if(!((temp_whole/10)%10)) { text[0] = ' '; text[1] = '-'; text[2] = (temp_whole%10 + 48); // Extract ones digit } if((temp_whole/10)%10) { text[0] = '-'; text[1] = ((temp_whole/10)%10 + 48); // Extract tens digit text[2] = (temp_whole%10 + 48); // Extract ones digit } break; } // Extract temp_fraction and convert it to unsigned int temp_fraction = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625; // Convert temp_fraction to characters text[4] = temp_fraction/1000 + 48; // Extract thousands digit text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit /* if(T==1) ( test cu if-uri pt. afisaj temperatura) { if((temp_whole/10)%10) { text[0] = ('-'); text[1] = (temp_whole/10)%10 + 48; // Extract tens digit text[2] = temp_whole%10 + 48; // Extract ones digit } else { text[0] = (' '); text[1] = ('-'); text[2] = temp_whole%10 + 48; // Extract ones digit } T=0; } else // if (temp_whole/100) { if(!(temp_whole/100)) //&& (temp2write & 0x8000)) text[0] = ' '; if(temp_whole/100) text[0] = temp_whole/100 + 48; if(!(temp_whole/10)%10) text[1] = ' '; else text[1] = (temp_whole/10)%10 + 48; // Extract tens digit text[2] = temp_whole%10 + 48; // Extract ones digit // Extract temp_fraction and convert it to unsigned int temp_fraction = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625; // Convert temp_fraction to characters text[4] = temp_fraction/1000 + 48; // Extract thousands digit text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit } */ } void ReadTemp() // Perform temperature reading { Ow_Reset(&PORTD, 0); // Onewire reset signal Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM Ow_Write(&PORTD, 0, 0x44); // Issue command CONVERT_T if (time>50) // Delay for temp conversion (Temperature Conversion Time 750ms Max) { Ow_Reset(&PORTD, 0); Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM Ow_Write(&PORTD, 0, 0xBE); // Issue command READ_SCRATCHPAD temp = Ow_Read(&PORTD, 0); temp = (Ow_Read(&PORTD, 0) << 8) + temp; time=0; } } const char gradc[] = {16,6,9,8,8,9,6,0}; // Degree celsius symbol void celsius(char pos_row, char pos_char) { char i; Lcd_Cmd(64); for (i = 0; i<=7; i++) Lcd_Chr_CP(gradc[i]); Lcd_Cmd(_LCD_RETURN_HOME); Lcd_Chr(pos_row, pos_char, 0); } void Display_Temp() // Display Temperature { Lcd_Out(2,10,text); Display_Temperature(temp); ReadTemp(); } void Overtemp() // Overtemperature subroutine{ if(!(temp & 0x8000)) { scov=0; y=0; Lcd_Cmd(_LCD_CLEAR); PORTB.F1=0; // Relay OFF while (temp>1280) { celsius(2,16); // Degree celsius symbol Display_Temp(); // Display temperature if(scov<1500) { if(y>10) { Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt14)); // Write text "Overtemperature!" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt15)); // Write text "T>90" in second row celsius(2,5); // Write celsius symbol after "T>90" in second row } if(y>150) { Tone3(); Lcd_Cmd(_LCD_CLEAR); y=0; } } if(scov>1550) { if(y>10) { Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt14)); // Write text "Overtemperature!" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt15)); // Write text "T>90" in second row celsius(2,5); // Write celsius symbol after "T>90" in second row } if(y>1000) { Tone3(); Lcd_Cmd(_LCD_CLEAR); y=0; scov=1551 ; } } } } Lcd_Cmd(_LCD_CLEAR);} void volt_ADC() // Reading the analog inputs (ADC) { Voltage = 0; for (ADCx=0; ADCx<10; ADCx++) { Voltage += ADC_Read(1); // Reading voltage values from channel 1 Delay_us(50); } Voltage = Voltage/ADCx; // Voltage calculation V = (long)Voltage*3500; // Millivolts conversion V = V/1023; // 0...1023 => 0...3500mV } void crt_ADC() // Reading the analog inputs (ADC) { Current = 0; for (ADCx=0; ADCx<10; ADCx++) { Current += ADC_Read(0); // Reading current values from channel 0 Delay_us(50); } Current = Current/ADCx; // Current calculation A = (long)Current*3500; // Millivolts conversion A = A/1023; // 0..1023 => 0...3500mV } void Display_voltage () { ch = V/1000; // Extract tens digit 10.00 if (ch==0) Lcd_Chr(1,1,32); else Lcd_Chr(1,1,48+ch); // Display results in ASCII format ch = (V/100) % 10; // Extract ones digit 01.00 Lcd_Chr_CP(48+ch); // Display results in ASCII format Lcd_Chr_CP('.'); // Display caracter '.' ch = (V/10) % 10; // Extract tenths digit 00.10 Lcd_Chr_CP(48+ch); ch = V % 10; // Extract hundredths digit 00.01 Lcd_Chr_CP(48+ch); LCD_Chr_CP (units[0]); // Print "V" after voltage value Delay_us(10); } void Display_current () { ch = A/1000; // Extract tens 10.00 if (ch==0) Lcd_Chr(1,11,32); else Lcd_Chr(1,11,48+ch); // Display results in ASCII format ch = (A/100) % 10; // Extract ones digit 01.00 Lcd_Chr_CP(48+ch); // Display results in ASCII format Lcd_Chr_CP('.'); // Display caracter '.' ch = (A/10) %10; // Extract tenths 00.10 Lcd_Chr_CP(48+ch); // Display results in ASCII format ch = A % 10; // Extract hundredths 00.01 Lcd_Chr_CP(48+ch); Lcd_Chr_CP(units[1]); // Print "A" after current value Delay_us(10); // Ten microseconds delay } void Display_power () { Pw = V*A/1000; // Power calculation ch = Pw/1000; // Hundreds digit calculation and display if (ch==0) Lcd_Chr(2,1,32); else Lcd_Chr(2,1,48+ch); ch = (Pw/100) % 10; // Tens digit calculation and display if (ch==0 && (Pw/1000==0)) Lcd_Chr(2,2,32); else Lcd_Chr(2,2,48+ch); ch = (Pw/10) %10; // Units digit calculation and display Lcd_Chr_CP(48+ch); Lcd_Chr_CP('.'); // Display caracter '.' ch = (Pw/1) % 10; // Tenths digit calculation and display Lcd_Chr_CP(48+ch); Lcd_Chr_CP(units[2]); // Print "W" after power value } void display_short() // Short circuit subroutine { char a; PORTB.F1=0; // Relay OFF Lcd_Cmd(_LCD_CLEAR); y=0; scov=0; sc=0; do { if(sc<1500) a=1; if(sc>1500) a=2; switch(a) { case 1: if(y<10) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt8)); // Write text "Output short" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt9)); // Write text "circuit detected" in second row Tone3(); Tone1(); scov=0; y=50; } if((y>150)&&(scov<250)) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt10)); // Write text "Please remove" in first row Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt11)); // Write text "short circuit!" in second row Tone1(); Tone3(); scov=250; } if(scov>350) { y=0; } break; case 2: if(y<10) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt8)); // Write text "Output short" in first row Lcd_Out(2,1,CopyConst2Ram(msg,LCD_txt9)); // Write text "circuit detected" in second row Tone3(); Tone1(); scov=0; y=50; } if((y>1000)&&(scov<1650)) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt10)); // Write text "Please remove" in first row Lcd_Out(2,3,CopyConst2Ram(msg,LCD_txt11)); // Write text "short circuit!" in second row Tone1(); Tone3(); scov=1650; } if(scov>2300) { y=0; } break; } if(tmp>50) // Delay for temp conversion (Temperature Conversion Time 750ms Max) { ReadTemp(); tmp=0; } if((temp>625)&&(!(temp & 0x8000))) PORTD.F1=1; // If temp. is positive and > 40 start cooler if(temp<480) PORTD.F1=0; // If temp is < 30 stop cooler volt_ADC(); // Read voltage } while(V>0); // Do print_scurt while voltage > 0 Lcd_Cmd(_LCD_CLEAR); x=1; // Set flag x} void display_overcurrent() // Overcurrent subroutine { PORTB.F1=0; // Relay OFF Lcd_Cmd(_LCD_CLEAR); scov=0; y=0; //PORTB.F0=1; do { if(scov<1500) { if(y>10) { Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt12)); // Write text "OVERCURRENT" in first row Lcd_Out(2,5,CopyConst2Ram(msg,LCD_txt13)); // Write text "I > 10A" in second row } if(y>150) { Tone2(); Lcd_Cmd(_LCD_CLEAR); y=0; } } else //if(scov>=1550) { if(y>5) { Lcd_Out(1,3,CopyConst2Ram(msg,LCD_txt12)); // Write text "OVERCURRENT" in first row Lcd_Out(2,5,CopyConst2Ram(msg,LCD_txt13)); // Write text "I > 10A" in second row } if(y>1000) { Tone2(); Lcd_Cmd(_LCD_CLEAR); y=0; } scov=1500 ; } if(tmp>50) // Delay for temp conversion (Temperature Conversion Time 750ms Max) { ReadTemp(); tmp=0; } if((temp>625)&&(!(temp & 0x8000))) PORTD.F1=1; // If temp.is positive and > 40 start cooler if(temp<480) PORTD.F1=0; // If temp is < 30 stop cooler volt_ADC(); // Read voltage } while(V>0); // Do print_overload while voltage > 0 Lcd_Cmd(_LCD_CLEAR); x=1; // Set flag x } void main(){ TRISB=0; // Make PORTB pin an output PORTB=0; // Set PORTB to 0 ADCON1 = 0x88; // Configure Vref, and analog channels TRISA = 0xFF; // Designate PORTA as input TRISD = 0xFD; // Designate PORTD as input, RD1 output OPTION_REG = 0; // Clear option register OPTION_REG = 0b10000111; // Prescaler is assigned to the Timer0, Prescaler = 256 INTCON = 0; // Clear the interrpt control register INTCON = 0b10100000; // Bit7 global interrupt enable, Bit5 TMR0 overflow interrupt enable TMR0 = 4; // Preset for timer register PORTD.F1=0; // Set PORTD pin 1 to 0 //PORTB.F1=0; // Set PORTB pin 1 to 0 Sound_Init(&PORTB, 0); // Configures the MCU pin 0 for sound generation Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off show_intro(); // Show splash screen Lcd_Cmd(_LCD_CLEAR); Delay_ms(10); // 10 milliseconds delay time=0; while(1) // Endless loop { do { volt_ADC(); // Read voltage crt_ADC(); // Read current x=0; // Reset flag x if((V==0) && (A>0)) display_short(); // Check for output short circuit if((V>0) && (A>1000)) display_overcurrent(); // Check for output overcurrent } while(x>0); // Do while x=1, means that the subroutine short or overcurrent has finished PORTB.F1=1; // Relay ON PORTB.F0=0; // Set PORTB pin 0 to 0 celsius(2,16); // Display degree celsius symbol row 2 col 16 Display_voltage(); Display_current(); Display_power(); Display_Temp(); if((temp>625)&&(!(temp & 0x8000))) PORTD.F1=1; // If temp.is positive and > 40 start cooler if(temp<480) PORTD.F1=0; // If temp is < 30 stop cooler if(temp>1450) Overtemp(); // If temp is > 90 do overtemp }} Hello Danpin. I tried to compile your code with mikroc ver 3.2 but it gives couple of errors and compilation fails. Would you please let me know which version of MikroC you used for this. Thank you. Link spre comentariu
danpin Postat Noiembrie 22, 2014 Partajează Postat Noiembrie 22, 2014 Hello kooroshi60, sorry for the late response. The code was written and compiled with version 6.0.0. (if you have not solved meantime). Link spre comentariu
ROBERT78 Postat Decembrie 20, 2014 Partajează Postat Decembrie 20, 2014 Buna!! Am facut si eu acest voltampermetru....am si programat picu dar problema e ca dupa ce am programat am observat ca e protejat hexu..imi apare (code protect) si nu mai reusesc sa programaez cu alt hex nu ma lasa...imi apare write failed at adres 00000..cineva poate sa ma ajute cu sfaturi idei cum se poate rezolva aceasta problema...sau se poate???Multumesc Link spre comentariu
Vizitator proiect_01 Postat Decembrie 20, 2014 Partajează Postat Decembrie 20, 2014 Incearca erase. Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum