Hallöchen.. Ich habe mir von ELV das PPS 5330 Labornetzteil als Bausatz gekauft und zusammengebaut. Alles hat bestens funktioniert. Nur ein kleiner Fehler meinerseits mit der Reflektorscheibe (siehe Link: Beitrag "Re: Joy-IT RD6006" ). Kleines Preview von mir mit falsch eingebauter Reflektorscheibe: https://youtu.be/MjL6gLWncd4 2.Video zeigt Temperaturmessung bei großer Last: https://youtu.be/GwYWNdFv-LQ Das Kühlaggregat im Labor-Netzteil kann unter Belastung bis über 80 °C heiß werden. Aus diesem Grund möchte ich eine Temperaturanzeige in das Netzteil integrieren, die mir die aktuelle Temperatur am Kühlaggregat anzeigt. Da es schon eine LCD-Anzeige und einen Temperatursensor an geeigneter Stelle gibt, habe ich mir überlegt, dies zu nutzen und die Leistungsanzeige auf dem LCD-Display alternierend mit einer Temperaturanzeige zu kombinieren (siehe 3.Bild). Leider gibt es im Internet für den verbauten ATmega88 Mikrocontroller von ELV keinen frei verfügbaren Quellcode. Also habe ich mich entschlossen die Software neu zu schreiben und eine Temperaturanzeige und wenn möglich eine USB Schnittstelle zu integrieren. Die Hardware Als erstes habe ich mir den seriellen Datenstrom zum LCD-Controller angesehen. Hierbei handelt es sich um eine SPI-Schnittstelle mit 3 Steuerleitungen (MOSI,MISO und CLK) und einer Taktrate von 500KHz. Über die Mosi-Leitung werden syncron zum Takt 8Bit-Daten vom ATmega88 zum LCD Controller übertragen. Der LCD Controller signalisiert mit einem Low-Pegel auf der MISO Leitung das er bereit ist, Daten vom ATMEGA88 zu empfangen. Bei einem High-Pegel stoppt die Übertragung vom Mikrocontroller. Mit meinem Rigol-Scope MSO5104 konnte ich die SPI Daten analysieren. Dazu habe ich die Datenleitung (MOSI) vom Mikrocontroller IC200 an den 1.Kanal angeschlossen und die Taktleitung (CLK) an den 2.Kanal. Die MISO Leitung liegt auf Kanal 3. Wie mann im 4.Bild erkennen kann werden für die einzelnen Anzeige Elemente zB die Spannung insgesamt 5 Datenbytes übertragen. Das 1.Datenbyte (43h) ist das Adressregister für den Spannungswert. Die nachfolgenden 4 Datenbytes sind die vier Dezimalstellen für den Spannungswert. Die Strom- und Leistungsanzeige funktioniert ähnlich. Ein Adressregister gefolgt von 4 Datenbytes für den 4stellige Wert. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Ich möchte eine Temperaturanzeige in das Netzteil integrieren, Das geht am einfachsten und vermutlich auch am billigsten mit einem Fertigthermometer für rund 3 EUR von ebay o.ä.
Rolf D. schrieb: > ELV das PPS 5330 ... oh oh, ist die Front von dem Teil hässlich! Das wäre dann gleich ein Showstopper für mich.
Rolf D. schrieb: > ELV das PPS 5330 Labornetzteil .. der Bausetz kostet echt 149€? Warum gibt Mann für 30V/3A soviel aus, was waren da deine Argumente dafür? Für rund 80-100€ bekommst du ein Labornetzteil fertig aufgebaut und dann auch nicht so hässlich, allerdings als Schaltnetzteil.
merciMerci schrieb: >> ELV das PPS 5330 > ... oh oh, ist die Front von dem Teil hässlich! Ja, da schadet auch ein zusätzliches Loch für ein Thermometer nicht.
Das Designe und die verbaute Technik finde ich nicht schlecht. Eine weitere Anzeige für die Temperatur gefällt mir nicht so gut. Mir gehts eigentlich um den Bastelspaß und das Verständnis der Netzteilschaltung.
:
Bearbeitet durch User
Hallöchen.. Ich habe eine Bitte. Durch einen dummen Fehler am SPI Port des ATmega88 habe ich die Firmware des PPS 5330 geschrottet. Das Auslesen des ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das Hexfile binhaltet nur Datenmüll (siehe Anhang). Kann mir vielleicht jemand helfen ? Vorab schon mal vielen Dank!
Rolf D. schrieb: > Hallöchen.. > > Ich habe eine Bitte. Durch einen dummen Fehler am SPI Port des ATmega88 > habe ich die Firmware des PPS 5330 geschrottet. Das Auslesen des > ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das > Hexfile binhaltet nur Datenmüll (siehe Anhang). Kann mir vielleicht > jemand helfen ? Hast Du schon mal bei ELV nachgefragt?
Vielleicht sollte ich das tun. Aber ob die das machen ist eine andere Frage. Denke eher nicht :(
Rolf D. schrieb: > Vielleicht sollte ich das tun. Aber ob die das machen ist eine andere > Frage. Denke eher nicht :( Insbesondere wenn Du noch die Originalrechnung hast, würde sich zumindest eine Anfrage lohnen.
Ich arbeite zur Zeit mit einem zweiten ATmega328P "Nano" um das LCD-Display anzusteuern. Eigentlich hatte ich vor, die SPI-Daten vom ATmega88 über einen 2.Controller zu leiten, dann für die Temperaturanzeige abzuändern und dann zum LCD-Controller zu senden. Bei dieser ganzen Umsteckerrei am SPI Port und am Programmer ist es dann passiert.
:
Bearbeitet durch User
So.. Anfrage bei ELV läuft. Bin gespannt und warte mal ab was die sagen :)
Hallo Rolf, ich finde Dein Projekt recht spannend, hast Du den kompletten Datenstrom zum Display schon 'entschlüsselt'?
Der Weilen versuch ich schon mal den Temperatursensor über den speziellen AD-Wandler auszulesen (siehe Bild). So wie ich das verstehe, wird über einen Integrator IC5 die Aufladezeit eines Kondensators C49 ermittelt und daraus der Temperaturwert berechnet. Der Messvorgang wird mit Starten eines 16Bit Timers im ATmega und dem Setzen von Eingang 2 oder 3 von Multiplexer IC6 gestartet. Vorher wird der Integrator IC5 über den Multiplexer Eingang 5 zurückgesetzt. Erreicht der Integratorausgang die gleiche Spannung wie am Temperatursensor wird Transistor T10 leitend und ein Interrupt-Eingang am ATmega angesteuert. Als Folge stoppt der Timer und der Wert kann ausgelesen werden. Danach folgt die Berechnung für den Temperaturwert und die Anzeige auf dem Display. Gruß Rolf
Goran E. schrieb: > Hallo Rolf, ich finde Dein Projekt recht spannend, hast Du den > kompletten Datenstrom zum Display schon 'entschlüsselt'? Fast alle Anzeige Elemente sind entschlüsselt. Weil ich versehentlich den eingebauten ATmega88 geflasht habe, fehlen zum Teil aber noch die Punkte und Unterstriche (siehe Bilder). Für Spannungs- und Stromwerte muss zuerst die Element Adresse und nachfolgend 4 Bytes für den Nummerischen Wert von 0-9 (50hex - 59hex) gesendet werden. 5Fh ist fürs Ausbenden einer Dezimalstelle. Gruß Rolf
:
Bearbeitet durch User
merciMerci schrieb: > oh oh, ist die Front von dem Teil hässlich! Dann erleuchte uns doch mal mit einem Beispiel eines tollen Frontplattendesigns. Vor allem bei den von dir vorgeschlagenen Geräten: merciMerci schrieb: > Für rund 80-100€ bekommst du ein Labornetzteil fertig aufgebaut Ach so du bist erst 10 und steht auf bonbonbuntes Chonadesign :-) SCNR
Harald W. schrieb: > Rolf D. schrieb: >> Hallöchen.. >> >> Ich habe eine Bitte. Durch einen dummen Fehler am SPI Port des ATmega88 >> habe ich die Firmware des PPS 5330 geschrottet. Das Auslesen des >> ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das >> Hexfile binhaltet nur Datenmüll (siehe Anhang). Kann mir vielleicht >> jemand helfen ? > > Hast Du schon mal bei ELV nachgefragt? Hallöchen.. Bezüglich meiner Anfrage an ELV, ob Sie mir die Firmware für das PPS 5330 zusenden könnten, habe ich leider eine negative Antwort erhalten. Das heißt für mich, entweder die Firmware selber schreiben oder hoffen und bangen, dass vielleicht ein User die Firmware von seinem Gerät auszulesen kann und mir zuschickt. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Bezüglich meiner Anfrage an ELV, ob Sie mir die Firmware für das PPS > 5330 zusenden könnten, habe ich leider eine negative Antwort erhalten. Das finde ich von einer Firma, die vom Verkauf von eher überteuerter Ware lebt, mehr als seltsam. Also sollte man wohl in Zukunft eher nicht mehr bei denen kaufen.
Hallo Mein Standpunkt ist der von OpenSource auch in meinen Projekten. Ein schönes Beispiel sind die Produkte von Mutable instruments https://mutable-instruments.net/. Alles OpenSource und trotzdem ist die Firma kommerziell erfolgreich. Mein OpenSource Projekt "DEGENERATOR": https://www.sequencer.de/synthesizer/threads/avr-synthesizer-wave-1-de-generator.87599/page-20 Gruß Rolf
:
Bearbeitet durch User
Lach schrieb: > merciMerci schrieb: >> oh oh, ist die Front von dem Teil hässlich! > > Dann erleuchte uns doch mal mit einem Beispiel eines tollen > Frontplattendesigns. Jepp, die Kritik ist mir auch nicht ganz klar. Sicherlich hätte man Strom- und Spannungseinstellung getrennt anbieten können, aber optisch finde ich die Netzteile durchaus ok (damals noch für €99 als Bausatz). Insbesondere sind das Vollmetallgehäuse. > Vor allem bei den von dir vorgeschlagenen Geräten: Wer ernsthaft Schaltnetzteile (mit all ihren Nachteilen) für diesen Leistungsbereich und die daraus offenkundigen Anwendungen im Labor erwägt, ist nicht wirklich ernstzunehmen. Für das Geld ist das PPS5330 wirklich ok: Ströme und Spannungen lassen sich - messbar - milliampere/-voltgenau einstellen und oft benötigte Spannungen speichern. Was mich etwas stört, ist die lange Anstiegszeit der Spannung beim Betrieb aus dem Standby heraus. Rolf D. schrieb: > Bezüglich meiner Anfrage an ELV, ob Sie mir die Firmware für das PPS > 5330 zusenden könnten, habe ich leider eine negative Antwort erhalten. > Das heißt für mich, entweder die Firmware selber schreiben oder hoffen > und bangen, dass vielleicht ein User die Firmware von seinem Gerät > auszulesen kann und mir zuschickt. Erstmal ein dickes Lob an Dich, dass Du die Dinger selbst programmieren möchtest und die Dinge, die Du schon rausgefunden hast. Ich muss mir mal den Schaltplan zu Gemüte führen und würde mal einen Ausleseversuch mit einem originalen avrispmkII starten. Wie genau hast Du Deinen Controller ausgelesen (nicht dass ich denselben Fehler auch mache)? Ich habe hier zwei Mal Softwareversion 1.1
Kleine OffTopic-Frage: Wie kann man die beiden Bananenbuchsen des PPS5330 entfernen? Bekomme das einfach nicht hin. Möchte möglichst wenig Gewalt anwenden, da die Frontplatte recht empfindlich ist.
Der Zusammenbau ist schon etwas her, aber ich meine, die wären ganz normal von hinten per Mutter verschraubt (so sieht's auch auf den Fotos der Anleitung aus). Also: einfach öffnen und gucken :-)
Rolf D. schrieb: > Das Auslesen des > ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das > Hexfile binhaltet nur Datenmüll (siehe Anhang). Da sind wohl schlicht die Lockbits gesetzt, eben damit die Firmware nicht ausgelesen werden kann.
Rolf D. schrieb: > Ja Rundmutter ist von hinten aufgeschraubt. Gibt sogar ein Spezialwerkzeug dafür, 2 Zangen tuns auch.
hinz schrieb: > Rolf D. schrieb: >> Das Auslesen des >> ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das >> Hexfile binhaltet nur Datenmüll (siehe Anhang). > > Da sind wohl schlicht die Lockbits gesetzt, eben damit die Firmware > nicht ausgelesen werden kann. Hallo Hinz, dann würde der Anfang des Hex-Files nicht mit der Software auf meinem ATmega Ersatz-Board übereinstimmen. Gruß Rolf
:
Bearbeitet durch User
Vielen Dank für Tipps :) Die Buchsen konnte ich mittels 9er Maulschlüssel und Zange gut demontieren.
@Rolf: Du hast die Frage von Chris gelesen? Chris D. schrieb: > ch muss mir mal den Schaltplan zu Gemüte führen und würde mal einen > Ausleseversuch mit einem originalen avrispmkII starten. > > Wie genau hast Du Deinen Controller ausgelesen (nicht dass ich denselben > Fehler auch mache)? > > Ich habe hier zwei Mal Softwareversion 1.1
Hallo Chris Der Anschluss für den ISP Programmer sieht so aus (siehe 1.Bild). 2.Bild Anschluss am AVRISPMKII Programmer. Schon mal vielen Dank für deine Mühe. Gruß Rolf
Hallöchen.. Ich programmiere gerade am Netzteil die PWM-Ansteuerung für Spannung und Strom. Könnte jemand mal überprüfen mit welcher PWM-Frequenz die U-Soll und I-Soll Anschlüsse im Netzteil angesteuer werden. Laut Rippel auf der Ausgangsspannung (siehe Bild) vermute ich so um die 2KHz. Danke. Gruß Rolf
Beitrag #6323266 wurde von einem Moderator gelöscht.
Mmmm.. Ich habe diesbezüglich hier im Forum noch keine negativen Erfahrungen gemacht. Gruß Rolf
Hallo.. Ich programmiere gerade die PWM-Ansteuerung für Spannung (U-Soll) und Strom (I-Soll) im Netzteil. Dafür habe ich die PWM-Ausgänge OCR1A und OCR1B im ATmega328 benutzt und diese auf eine Auflösung von 14Bit und eine PWM-Frequenz von 1KHz eingestellt. Das PWM-Steuersignal wird im Netzteil über einen Tiefpass (R 42, R 43, C 27 sowie R 52, R 53 und C 34) in eine proportionale Gleichspannungen gewandelt. Der Spannungswert für U-Soll ist in mV angegeben. Um eine größere Genauigkeit bei den Berechnungen zu erhalten, habe ich die Werte um den Faktor 1000 skaliert. Youtube: https://youtu.be/PlK1gVf0LB4 Beispiel für U-Soll
1 | {
|
2 | DDRB |= (1 << DDB1)|(1 << DDB2); |
3 | // PB1 and PB2 is now an output
|
4 | |
5 | ICR1 = 0x3FFF; |
6 | // set TOP to 16383 14Bit/1KHz
|
7 | |
8 | // set U-Soll
|
9 | uint8_t Digi_offset = 67; |
10 | uint16_t Umax = 30000; // mV |
11 | uint32_t Usoll = 20000; // mV |
12 | uint32_t PWM_value = 15540; // 15540 ~ 30.0V |
13 | uint16_t OCR_value = 0; |
14 | PWM_value = (PWM_value * 1000); |
15 | OCR_value = (uint32_t)(((PWM_value) / Umax) * Usoll) / 1000; |
16 | |
17 | //set PWM (U-Soll)
|
18 | OCR1A = Digi_offset + OCR_value; |
19 | |
20 | OCR1B = 16382; // Ampre |
21 | // set PWM for 100% duty cycle @ 16bit
|
22 | |
23 | TCCR1A |= (1 << COM1A1)|(1 << COM1B1); |
24 | // set none-inverting mode
|
25 | |
26 | TCCR1A |= (1 << WGM11); |
27 | TCCR1B |= (1 << WGM12)|(1 << WGM13); |
28 | // set Fast PWM mode using ICR1 as TOP
|
29 | |
30 | TCCR1B |= (1 << CS10); |
31 | // START the timer with no prescaler
|
32 | |
33 | }
|
:
Bearbeitet durch User
Habe gerade gesehen das man Usoll auch auf 16Bit setzen kann. Das spart ein wenig Prozessor Ressourcen ;)
Rolf D. schrieb: > Durch einen dummen Fehler am SPI Port des ATmega88 habe ich die Firmware > des PPS 5330 geschrottet. Ähm, d.h. du hast für 150 einen Bausatz für ein 40V/3A Netzteil gekauft, erfolgreich zusammengebaut und nun bei der Analyse wie du eine Temperaturanzeige nachrüsten kannst so geschrottet, dass du ohne Firmware dastehst, weil ELV Asi wie immer reagiert. Da bleibt wohl nur, den Focus deines Bastelprojekts so zu verändern, dass du eine neue Firmware schreibst und dann veröffentlichst. Bei der kannst du gleich eine Temperaturanzeige einbauen. Obwohl so was bei funktionierenden Geräten überflüssig ist, eine galvanisch getrennte USB Programmierbarkeit als MODBus Device aber sehr wertsteigernd wäre. Was ich nicht ganz verstehe, ist der CD4051 aufgebaute A/D Wandler. Die haben echt diese ungenaue Schaltung drin, obwohl der ATmega88 8 eigene Analogkanäle besitzt ? Die brauchen 4 Pind (ADW und AD0, AD2, AD2) um 4 Analogwerte zu messen. Da sollte man die Schaltung restlos entsorgen, und an 4 Analogeingänge des ATmega legen (den man dafür ggf. umverdrahten muss) mit interner Referenz. Die ist zwar um +/-10% ungenau, aber ein mal kalibriert bleibt die 1000x stabiler als die Versorgungsspannung. Nein, die 10 bit sind nicht zu wenig. Auch wenn dein externer Wandler mit 16 bit timer auflöst, ist er erheblich unlinearer als 10 bit. Macht bei 30V halt 0.03V Auflösung. Merkwürdig finde ich, dass beim Display IST und SOLL angezeigt wird, die Eingabe neuer SOLL-Werte aber wohl im IST Display gemacht wird. Da hat wohl jemand bei ELV sein Gehirn an der Garderobe abgegeben. Ich würde die Eingsbe aufs kleine Display verlagern, da dort Unterstriche fehlen wohl durch blinkende Ziffer
Hier die Software zum Ansteuer vom Display im PPS 5330 Netzteil. Der Code ist noch nicht optimiert. Für die Entwicklung einer eigenen Software benutze ich ein ATmega328P "NANO" Board. Dieser besitzt im Vergleich zu dem ATmega88 im Netzteil einen größeren Programmspeicher und mehr Port-Leitungen. Die serielle Datenleitung (MOSI, MISO, CLK) zum Display habe ich über drei Port-leitungen mit dem ATmega328 verbunden und steuer diese softwaremäßig an. Die SPI-Schnittstelle im ATmega328 ist mit dem Programmieradapter verbunden.
1 | #define F_CPU 16000000UL
|
2 | |
3 | #include <avr/io.h> |
4 | #include <util/delay.h> |
5 | #include <avr/interrupt.h> |
6 | |
7 | #define SOFT_SPI_MOSI_PORT PORTD
|
8 | #define SOFT_SPI_CLK_PORT PORTD
|
9 | #define SOFT_SPI_MOSI_DDR DDRD
|
10 | #define SOFT_SPI_CLK_DDR DDRD
|
11 | #define SOFT_SPI_MISO_DDR DDRD
|
12 | #define RESET_DDR DDRD
|
13 | #define SOFT_SPI_MOSI_BIT PD4
|
14 | #define SOFT_SPI_MISO_BIT PD2
|
15 | #define SOFT_SPI_CLK_BIT PD3
|
16 | #define SOFT_SPI_MISO_PIN PD2
|
17 | |
18 | |
19 | // Software SPI
|
20 | void SOFT_SPI_init(void){ |
21 | // MOSI und CLK auf Ausgang setzen
|
22 | SOFT_SPI_MOSI_DDR |=(1<<SOFT_SPI_MOSI_BIT); |
23 | SOFT_SPI_CLK_DDR |=(1<<SOFT_SPI_CLK_BIT); |
24 | |
25 | // MOSI und CLK auf HIGH setzen
|
26 | SOFT_SPI_MOSI_PORT|=(1<<SOFT_SPI_MOSI_BIT); |
27 | SOFT_SPI_CLK_PORT |=(1<<SOFT_SPI_CLK_BIT); |
28 | |
29 | // MISO auf Eingang setzen
|
30 | SOFT_SPI_MISO_DDR &=~(1<<SOFT_SPI_MISO_BIT); |
31 | |
32 | |
33 | }
|
34 | |
35 | |
36 | SPI_wr2(unsigned char dataout) |
37 | {
|
38 | uint8_t datain=0; |
39 | //das Byte wird Bitweise nacheinander Gesendet MSB zuerst
|
40 | for (uint8_t a=8; a>0; a--){ |
41 | datain<<=1; //Schieben um das Richtige Bit zusetzen |
42 | SOFT_SPI_CLK_PORT &=~(1<<SOFT_SPI_CLK_BIT); // Clock auf LOW |
43 | |
44 | if (dataout & 0x80){ //Ist Bit a in Byte gesetzt |
45 | SOFT_SPI_MOSI_PORT |=(1<<SOFT_SPI_MOSI_BIT); //Set Output High |
46 | }
|
47 | else{ |
48 | SOFT_SPI_MOSI_PORT &=~(1<<SOFT_SPI_MOSI_BIT); //Set Output Low |
49 | }
|
50 | |
51 | _delay_us(1); |
52 | if (SOFT_SPI_MISO_PIN & (1<<SOFT_SPI_MISO_BIT)) //Lesen des Pegels |
53 | {
|
54 | datain |= 1; |
55 | }
|
56 | |
57 | _delay_us(1); |
58 | SOFT_SPI_CLK_PORT |=(1<<SOFT_SPI_CLK_BIT); // Clock auf High |
59 | _delay_us(1); |
60 | dataout<<=1; //Schiebe um nächstes Bit zusenden |
61 | }
|
62 | _delay_us(100); |
63 | while(PIND & (1<<SOFT_SPI_MISO_BIT)); // LCD chip Bussy ? |
64 | |
65 | }
|
66 | |
67 | |
68 | int main(void) |
69 | {
|
70 | // Set the PORTD as Output:
|
71 | DDRD = 0xFF; |
72 | PORTD = 0x00; |
73 | |
74 | SOFT_SPI_init(); |
75 | |
76 | DDRB |= (1<<PB1); |
77 | PORTB |= (1<<PB1); |
78 | PORTB &= ~(1<<PB1); |
79 | |
80 | _delay_ms(1000); |
81 | SPI_wr2(0xF0); // Display löschen |
82 | _delay_ms(1000); |
83 | SPI_wr2(0xC1); // Beleuchtung einschalten |
84 | |
85 | SPI_wr2(0x43); // " 0.00 V" |
86 | SPI_wr2(0x50); |
87 | SPI_wr2(0x50); |
88 | SPI_wr2(0x50); |
89 | SPI_wr2(0x5D); |
90 | SPI_wr2(0x23); |
91 | SPI_wr2(0x05); |
92 | SPI_wr2(0x34); |
93 | SPI_wr2(0x22); |
94 | SPI_wr2(0x09); |
95 | SPI_wr2(0x31); |
96 | SPI_wr2(0x23); |
97 | SPI_wr2(0x06); |
98 | SPI_wr2(0x34); |
99 | |
100 | |
101 | SPI_wr2(0x47); // "0.000 A" |
102 | SPI_wr2(0x50); |
103 | SPI_wr2(0x50); |
104 | SPI_wr2(0x50); |
105 | SPI_wr2(0x50); |
106 | SPI_wr2(0x27); |
107 | SPI_wr2(0x03); |
108 | SPI_wr2(0x31); |
109 | SPI_wr2(0x27); |
110 | SPI_wr2(0x01); |
111 | SPI_wr2(0x34); |
112 | |
113 | SPI_wr2(0x23); // " 0.00 W" |
114 | SPI_wr2(0x03); |
115 | SPI_wr2(0x31); |
116 | SPI_wr2(0x4B); |
117 | SPI_wr2(0x50); |
118 | SPI_wr2(0x50); |
119 | SPI_wr2(0x50); |
120 | SPI_wr2(0x5E); |
121 | |
122 | |
123 | while(1) |
124 | {
|
125 | _delay_ms(2000); |
126 | SPI_wr2(0x23); // "W" off |
127 | SPI_wr2(0x03); |
128 | SPI_wr2(0x10); |
129 | SPI_wr2(0x4B); // "27.5C" |
130 | SPI_wr2(0x5C); |
131 | SPI_wr2(0x55); |
132 | SPI_wr2(0x57); |
133 | SPI_wr2(0x52); |
134 | SPI_wr2(0x23); |
135 | SPI_wr2(0x02); |
136 | SPI_wr2(0x31); |
137 | OCR0A = 128; |
138 | _delay_ms(2000); |
139 | SPI_wr2(0x23); // "W" on |
140 | SPI_wr2(0x03); |
141 | SPI_wr2(0x31); |
142 | SPI_wr2(0x4B); // "0.000 W" |
143 | SPI_wr2(0x50); |
144 | SPI_wr2(0x50); |
145 | SPI_wr2(0x50); |
146 | SPI_wr2(0x5E); |
147 | OCR0A = 20; |
148 | }
|
149 | |
150 | }
|
Hab ein kleines Video gemacht: https://youtu.be/u_zMiCXtVsI Gruß Rolf
MaWin schrieb: > Was ich nicht ganz verstehe, ist der CD4051 aufgebaute A/D Wandler. Die > haben echt diese ungenaue Schaltung drin, obwohl der ATmega88 8 eigene > Analogkanäle besitzt ? Die brauchen 4 Pind (ADW und AD0, AD2, AD2) um 4 > Analogwerte zu messen. Da sollte man die Schaltung restlos entsorgen, > und an 4 Analogeingänge des ATmega legen (den man dafür ggf. > umverdrahten muss) mit interner Referenz. Die ist zwar um +/-10% > ungenau, aber ein mal kalibriert bleibt die 1000x stabiler als die > Versorgungsspannung. Nein, die 10 bit sind nicht zu wenig. Auch wenn > dein externer Wandler mit 16 bit timer auflöst, ist er erheblich > unlinearer als 10 bit. Macht bei 30V halt 0.03V Auflösung. > > Merkwürdig finde ich, dass beim Display IST und SOLL angezeigt wird, die > Eingabe neuer SOLL-Werte aber wohl im IST Display gemacht wird. Da hat > wohl jemand bei ELV sein Gehirn an der Garderobe abgegeben. Ich würde > die Eingsbe aufs kleine Display verlagern, da dort Unterstriche fehlen > wohl durch blinkende Ziffer Hi MaWin Danke für dein Interesse. Der ADC im ATmega88 hat leider nur eine 10Bit Auflösung. Das reicht für eine genau Messwert-Analyse für 30V nicht aus. Beispiel: 10Bit Auflösung 1024 / 30V = 29mV Aus diesem Grund wurde ein hochauflösender 16Bit Timer benutzt, der die Aufladezeit eines Integrator misst. Die gemessene Zeit wird dann in einen Spannungswert umgerechnet. Klar das die Umwandlung dann etwas mehr Zeit benötigt als bei einem echten AD-Wandler. Als Referenzspannung für die Messungen dient hier ein LM385 mit 2.5V D16. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Das reicht für eine genau Messwert-Analyse für 30V nicht aus. Was genau soll denn da nicht ausreichen bei so einem LNG? Das soll ja jetzt keine hochgenaue Kiste sein. OK, mir waren die 10 bit auch etwas zu eng, ich hab deswegen einen MCP3208 (12bit ADC) eingesetzt in meinem LNG zum Auswerten der Potis und der Ist-Werte des LNGs
M. K. schrieb: > Rolf D. schrieb: >> Das reicht für eine genau Messwert-Analyse für 30V nicht aus. > > Was genau soll denn da nicht ausreichen bei so einem LNG? Das soll ja > jetzt keine hochgenaue Kiste sein. Du stellst eine Frage ... > OK, mir waren die 10 bit auch etwas zu eng, ich hab deswegen einen > MCP3208 (12bit ADC) eingesetzt in meinem LNG zum Auswerten der Potis und > der Ist-Werte des LNGs ... und beantwortest sie selbst. Einfach zu drollig.
Hallöchen.. Ich werde Heute versuchen, die Spannungsmessung über den speziellen AD-Wandler im Netzteil zu programmieren und bin dann auf die Genauigkeit der Messung gespannt. Gruß Rolf
Rolf D. schrieb: > Ich werde Heute versuchen, die Spannungsmessung ene Bitte, kannst du auch deinem Rigol mal ein Sinus zeigen fast von der unteren Displaykante zur oberen, und dann genau so nach oben oder unten rausschieben bitte. Plottet das Rigol am Rand weiter oder nicht? beide Bilder wären toll Danke
Rolf D. schrieb: > Der ADC im ATmega88 hat leider nur eine 10Bit Auflösung. Das reicht für > eine genau Messwert-Analyse für 30V nicht aus. Bloss: der diskret aufgebauter misst nicht genauer. Er erfindet nur ein paar bits dazu. Für genauer als 0.1% müssten Widerstände, Referenzspannungsquelle, OpAmp-Offsetspannung, Kondensatorkonstanz, dielektrische Absorption und Unabhängigkeit der Kapazität von der Spannung auch entsprechend genau sein. Das ist alles nicht der Fall.
Joachim B. schrieb: > Rolf D. schrieb: >> Ich werde Heute versuchen, die Spannungsmessung > > ene Bitte, kannst du auch deinem Rigol mal ein Sinus zeigen fast von der > unteren Displaykante zur oberen, und dann genau so nach oben oder unten > rausschieben bitte. Plottet das Rigol am Rand weiter oder nicht? > > beide Bilder wären toll > Danke Ja kein Problem. Hier meine Pics..
Rolf D. schrieb: > hinz schrieb: >> Rolf D. schrieb: >>> Das Auslesen des >>> ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das >>> Hexfile binhaltet nur Datenmüll (siehe Anhang). >> >> Da sind wohl schlicht die Lockbits gesetzt, eben damit die Firmware >> nicht ausgelesen werden kann. > > Hallo Hinz, > dann würde der Anfang des Hex-Files nicht mit der Software auf meinem > ATmega Ersatz-Board übereinstimmen. Es gibt mehr als ein einziges Lockbit.
> Er erfindet nur ein paar bits dazu. Ist doch egal. Hauptsache es sieht auf der Anzeige huebscher aus. :) > Für genauer als 0.1% müssten Widerstände, > Referenzspannungsquelle, OpAmp-Offsetspannung, Kondensatorkonstanz, > dielektrische Absorption und Unabhängigkeit der Kapazität von der Ich vermute mal da es ein Bausatz war, hat man auch einen Schaltplan und kann dann ganz einfach alle Bauteile verbessern. Ist vielleicht unoetig weil man bei Netzteilen mit 0.1V auskommt, aber schadet ja auch nicht. So kann man dann auch gleich die Anschaffung seines teuren Multimeter rechtfertigen das man zum kalibrieren braucht. :-) Olaf
Rolf D. schrieb: >> beide Bilder wären toll > Ja kein Problem. Hier meine Pics. danke, so ein tolles Gerät aber das machen sie immer noch falsch, beim Sinus ist es ja eindeutig, aber beim Rechteck liest man auf die Schnelle mal falsche Vpp ab, das nervt mich. Ich weiss die Vertikalauflösung ist begrenzt, aber die FW könnte im Zweifel das plotten auch sein lassen, TEK kann es ja auch (OK 9 bis 12 Bit) Aber ein 7-Bit Anzeige ist mir lieber als eine Falschanzeige.
:
Bearbeitet durch User
Das Display hat eine Color Grade Funktion. Darin wird beim Überschreiten des Bildschirmrandes die Wafeform rot gezeichnet.
:
Bearbeitet durch User
Da ich auch über so ein PPS5330 verfüge, hier eine kleine Messreihe (Herstellerkalibrierung):
1 | Einstellung (Volt) Messung (Volt, Multimeter) |
2 | |
3 | 3 3,00 |
4 | 5 5,00 |
5 | 12 11,99 |
6 | 15 14,99 |
7 | 18 17,99 |
8 | 24 23,98 |
9 | 27 27,98 |
10 | 30 29,97 |
Wobei die Auflösung laut Anleitung bei 14Bit liegt. Ich habe die PWM-Ansteuerung für Strom und Spannung auch auf 14Bit programmiert. Damit Beträgt die Spannungsauflösung 1.8mV und beim Strom 181uA.
:
Bearbeitet durch User
Martin schrieb: > Da ich auch über so ein PPS5330 verfüge, hier eine kleine Messreihe > (Herstellerkalibrierung): > >
1 | > |
2 | > Einstellung (Volt) Messung (Volt, Multimeter) |
3 | > |
4 | > 3 3,00 |
5 | > 5 5,00 |
6 | > 12 11,99 |
7 | > 15 14,99 |
8 | > 18 17,99 |
9 | > 24 23,98 |
10 | > 27 27,98 |
11 | > 30 29,97 |
12 | > |
13 | > |
Ja, ziemlich ähnliche Werte (bis auf die 27,98V ;-) haben wir hier auch gemessen (selbst kalibriert). Wie ich schon schrieb: so schlecht scheint die A/D-Einheit nicht zu sein - im Gegenteil: auch die Stromregelung ist wirklich gut. Wenn ich für einen Sensor 78mA benötige, dann kann ich die (messbar) auf +/- 1mA einstellen. @Rolf: am WE starte ich mal den Ausleseversuch - bis dahin habe ich leider noch zu viel zu tun.
@Martin Null Problemo. Ich hab Zeit. Ich habe die Wandlerfunktion für den AD-Wandler im Netzteil programmiert. Folgende Zeitwerte für die Spannungsmessung konnte ich am Kollektor (ADW-Ausgang) von Transistor T10 messen (Low-Impuls). Der Collektor liegt über einen Pullup Widerstand an +5V. Ausgangsspannung Zeit ======================== 0.1V = 3.71ms 1.0V = 1.76ms 2.0V = 1.24ms 3.0V = 950us 10V = 422us 20V = 246us 30V = 168us Jetzt muss ich diesen Zeitwert in einen Spannungswert umwandeln. Gruß Rolf
Rolf D. schrieb: > @Martin > Null Problemo. Ich hab Zeit. Der Beitrag stammt von Chris. Deine gemessenen Zeiten überzeugen mich nicht. Erwarte eher einen linearen Zusammenhang von t und U. Kannst du das Programm posten?
Die Zeiten habe ich mit dem Scope gemessen.
1 | void start_ADC() |
2 | {
|
3 | // clear intecrator
|
4 | PORTC |= (1<<ADC_AD0); |
5 | PORTC &= ~(1<<ADC_AD1); |
6 | PORTC |= (1<<ADC_AD2); |
7 | _delay_ms(1); |
8 | |
9 | // Voltage measurement
|
10 | PORTC &= ~(1<<ADC_AD0); |
11 | PORTC &= ~(1<<ADC_AD1); |
12 | PORTC &= ~(1<<ADC_AD2); |
13 | _delay_ms(10); |
14 | |
15 | /*
|
16 | // Temp1 measurement
|
17 | PORTC |= (1<<ADC_AD0);
|
18 | PORTC |= (1<<ADC_AD1);
|
19 | PORTC &= ~(1<<ADC_AD2);
|
20 | _delay_ms(10);
|
21 | */
|
22 | }
|
In der main wird start_ADC() permanent aufgerufen. Das Scope hängt am Kollektor von T10. Gruß Rolf
:
Bearbeitet durch User
Ich habe die Spannungsmessung noch mal etwas verändert und starte den Mess-vorgang wie folgt: 1. Eingang Nr.5 am Multiplexer IC6 aktivieren um den Integrator IC5d zu initialisieren. 5ms warten fürs Entladen von Kondensator C49 und warten auf High-Pegel am ADW-Ausgang von Transistor T10. 2. Eingang Nr.0 am Multiplexer für U-Mess aktivieren und Test-Pin für Scope auf High-Pegel setzen. 3. Auf Low-Pegel am ADW-Ausgang von Transistor T10 warten. Danach Test-Pin auf Low und kleine Pause von 5ms und neue Messung starten. Scope Bild: Gelb = ADW-Ausgang, Blau = Test-Pin Messwerte: 0.1V = 3.384ms 1.0V = 1.486ms 2.0V = 998us 3.0V = 780us 4.0V = 653us 5.0V = 569us 6.0V = 508us 7.0V = 461us 8.0V = 425us 9.0V = 395us 10.0V = 370us 20.0V = 242us 30.0V = 190us
1 | void start_ADC() |
2 | {
|
3 | // clear intecrator
|
4 | PORTC |= (1<<ADC_AD0); |
5 | PORTC &= ~(1<<ADC_AD1); |
6 | PORTC |= (1<<ADC_AD2); |
7 | _delay_ms(5); |
8 | while (PINC & (1<<ADC_ADW)); |
9 | |
10 | // Voltage measurement
|
11 | // Reset Timer
|
12 | PORTC &= ~(1<<ADC_AD0); |
13 | PORTC &= ~(1<<ADC_AD1); |
14 | PORTC &= ~(1<<ADC_AD2); |
15 | PORTC |= (1<<Test_Pin); // Test_flag = High |
16 | while (!(PINC & (1<<ADC_ADW))); |
17 | PORTC &= ~(1<<Test_Pin); // Test_flag = low |
18 | _delay_ms(5); |
19 | |
20 | /*
|
21 | // Temp1 measurement
|
22 | PORTC |= (1<<ADC_AD0);
|
23 | PORTC |= (1<<ADC_AD1);
|
24 | PORTC &= ~(1<<ADC_AD2);
|
25 | PORTC |= (1<<Test_flag); // Test_flag = High
|
26 | while (!(PINC & (1<<ADC_ADW)));
|
27 | PORTC &= ~(1<<Test_flag); // Test_flag = low
|
28 | _delay_ms(5);
|
29 | */
|
30 | }
|
Gruß Rolf
:
Bearbeitet durch User
Beitrag #6325017 wurde von einem Moderator gelöscht.
1 | Grün - Eingang Integrator |
2 | Blau - ADW-Ausgang |
3 | Rot - Ausgang Integrator |
4 | |
5 | 1. Phase (Ch. 5) - zurücksetzen des Integrators (ca. 0 V, 1 ms). |
6 | 2. Phase (Ch. 0) - Messspannung anlegen (x V, Dauer: 19 ms). |
7 | 3. Phase (Ch. 4) - Referenzspannung anlegen (-2,5 V bis Komparator High, Dauer 38 ms). |
8 | |
9 | x = 38 ms / 19 ms * 2,5 V = 5 V |
Gehe nach dem obigen Muster vor und liste die Spannungen/Zeiten auf. Eventuell die Wahl des Kanals (Ch.) in einem Befehl zusammenfassen und nicht auf mehrere verteilen. Die Zeiten und Spannungen im Bild sind "erfunden" und stimmen nicht mit dem PPS5330 überein.
Hallo Martin Vielen Dank für die tolle Erklärung. Ich hatte die Schaltung des AD-Wandlers falsch verstanden und gedacht, dass es sich bei der AD-Wandlung um ein Single-Slope Verfahren handelt. Aus diesem Grund habe ich nur die Aufladezeit des Kondensators gemessen statt die Entladezeit über Uref. Das war natürlich falsch. Der AD-Wandler im Netzteil arbeitet im Dual-Slope Verfahren. Hatte mich schon gewundert, was die negative Referenzspannung von -2.5V am Multiplexer bewirken soll. Link: http://www.vias.org/mikroelektronik/adc_dualslope.html Vielen Dank nochmals. Man lernt doch nie aus ;) Gruß Rolf
:
Bearbeitet durch User
Ja suppi.. Es hat funktioniert :) Die Messsung von U-Mess hat jetzt funktioniert. Die Messwerte am Scope haben jetzt einen linearen Zusammenhang von t und U (siehe Tabelle). Spannung Zeit =============== 1.0V = 824us 2.0V = 1.334ms 3.0V = 1.845ms 4.0V = 2.355ms 5.0V = 2.866ms 6.0V = 3.376ms 7.0V = 3.887ms 8.0V = 4.398ms 9.0V = 4.908ms 10.0V = 5.419ms 20.0V = 10.527ms 30.0V = 15.639ms Die Zeit-Differenz für 1.0V beträgt genau 511us. Es gibt einen positiven Offset den man bei 1V abziehen muss um auf einen linearen Zusammenhang zwischen den Messwerten zu kommen. Dieser Offset beträgt 824us - 511us = 313us Beispiel: 30 x 0.511 = 15.330 + 0.313 = 15.64ms
1 | void start_ADC() |
2 | {
|
3 | // clear ADC
|
4 | PORTC |= (1 << ADC_AD0) | (1 << ADC_AD2); |
5 | PORTC &= ~(1<<ADC_AD1); |
6 | _delay_ms(50); |
7 | |
8 | // set U-Mess for measurement
|
9 | PORTC &= ~((1 << ADC_AD0) | (1<<ADC_AD1) | (1<<ADC_AD2)); |
10 | _delay_ms(19); |
11 | |
12 | // start with measurment
|
13 | PORTC |= (1 << ADC_AD2) | (1 << Test_Pin); |
14 | while (PINC & (1<<ADC_ADW)); // wait until ADW-Signal is low (end of measurment) |
15 | PORTC &= ~(1<<Test_Pin); // clear Test-Pin |
16 | _delay_ms(38); |
17 | }
|
Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. Jetzt gibt es noch ein kleines Problemchen mit der Timer Einstellung. Die Auflösung der Messspannung liegt bei 10mV. Das sind 511us/100 = 5,1us. Bei 30V wären das 511us x 30 = 15.330us. Der Timer1 läuft bei 16Mhz MCU Takt und einem Vorteiler von 8 mit einer Frequenz von 2MHz ~ 0,5us. Die maximale Messzeit beträgt damit 32,767ms. Da ich den Timer1 schon für die 16Bit PWM Spannung- und Stromsteuerung verwendet habe, muss ich die Messung mit Timer0 bewerkstelligen. Der Timer0 hat aber nur ein 8Bit Zählregister. Das reicht für eine Messung im gesamten Spannungsbereich von 0-30V leider nicht aus. Also muss ich ein zweites Speicherregister erstellen, in dem der Timerüberlauf von Timer1 gezählt wird. Durch einen externen Interrupt vom ADW-Signal (T10) stoppt der Timer0 und ich kann die beiden Register (Timer1 und Speicherregister) auslesen. Die 16Bit Zahl ergibt dann meine Messzeit. Mal schaun ob ich das so umsetzen kann.. Ideen und Anregungen nehme ich gerne an. Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. So.. habs hinbekommen. Muss die Software aber noch etwas optimieren. Auf dem Display wird jetzt die Messzeit für die Spannung in Mikrosekunden angegeben. Da die ober Zeile nur 4stellig ist und das Messergebnis aber 5stellig, habe ich die 5.Zahlenstelle in die 2.Reihe verschoben. Kleines Video (Messspannung 5V): https://youtu.be/6rm5Og6tHkc Spannung Zeit =============== 1.0V = 824us 2.0V = 1.334ms 3.0V = 1.845ms 4.0V = 2.355ms 5.0V = 2.866ms 6.0V = 3.376ms 7.0V = 3.887ms 8.0V = 4.398ms 9.0V = 4.908ms 10.0V = 5.419ms 20.0V = 10.527ms 30.0V = 15.639ms Jetzt muss ich die Zeitwerte nur noch in Spannungswerte umsetzen :) Gruß Rolf
:
Bearbeitet durch User
Beitrag #6327112 wurde von einem Moderator gelöscht.
Beitrag #6327129 wurde von einem Moderator gelöscht.
Beitrag #6327198 wurde von einem Moderator gelöscht.
Hallöchen.. Ich habe jetzt die Spannungs-, Strom- und Temperaturanzeige programmiert (siehe Video). Ein wenig muss ich die Anzeigewerte noch korrigieren. Der Lüfter wird in Abhängigkeit von der Temperatur am Kühlkörper über den PWM-Ausgang von Timer2 gesteuert. Bei 70 Grad leuchtet die Warnmeldung "Overtemp." auf und der Lüfter wird mit voller Drehzahl angesteuert. Die Abschaltung bei 80 Grad muss ich noch programmieren. Jetzt folgt die Spannungs- und Stromeinstellung über den Encoder und die Anzeige auf der rechten Seite des Displays. Kleines Video: https://youtu.be/rZ79zxSLXU4 Berechnung von U-Mess aus den Timerwert
1 | void U_measurement () |
2 | {
|
3 | mess_flag = 1; |
4 | start_Measurement(U_Mess); |
5 | |
6 | while(mess_flag == 1){} // wait until measuring time ends |
7 | |
8 | uint16_t mess_x = (mess_time - 156); // offset bei 0.0 Volt |
9 | float result = (((float)mess_x * 148.9) / 50000); |
10 | |
11 | char buf[6]; |
12 | sprintf(buf,"%2.2f\n",result); // format result in string |
13 | |
14 | SPI_wr2(0x43); // print voltage "xx.xx" |
15 | |
16 | if (buf[2] == 46) // bei der Anzeige Kommastelle (ASCII-Zeichen 46) in result beachten |
17 | {
|
18 | SPI_wr2(buf[4]+32); |
19 | SPI_wr2(buf[3]+32); |
20 | SPI_wr2(buf[1]+32); |
21 | SPI_wr2(buf[0]+32); |
22 | }
|
23 | else
|
24 | {
|
25 | SPI_wr2(buf[3]+32); |
26 | SPI_wr2(buf[2]+32); |
27 | SPI_wr2(buf[0]+32); |
28 | SPI_wr2(0x5D); |
29 | }
|
30 | mess_time = 0; |
31 | mess_flag = 0; |
32 | }
|
Berechnung von I-Mess aus den Timerwert
1 | void I_measurement () |
2 | {
|
3 | mess_flag = 1; |
4 | start_Measurement(I_Mess); |
5 | |
6 | while(mess_flag == 1){} // wait until measuring time ends |
7 | |
8 | uint16_t i_mess = mess_time - 145; // Offset bei 0 Ampere |
9 | |
10 | float result = ((float)i_mess / 4.224666)/1000; |
11 | |
12 | char buf[6]; |
13 | sprintf(buf,"%1.3f\n",result); // format result in string |
14 | |
15 | SPI_wr2(0x47); // print ampere "x.xxx" |
16 | SPI_wr2(buf[4]+32); |
17 | SPI_wr2(buf[3]+32); |
18 | SPI_wr2(buf[2]+32); |
19 | SPI_wr2(buf[0]+32); |
20 | |
21 | mess_time = 0; |
22 | mess_flag = 0; |
23 | }
|
Berechnung der Temperatur T1 und PWM für den Fan aus dem Timerwert
1 | void T1_measurement() |
2 | {
|
3 | mess_flag = 1; |
4 | start_Measurement(T1_Mess); |
5 | |
6 | while(mess_flag == 1){} // wait until measuring time ends |
7 | |
8 | mess_time -= 5800; // = offset bei 0.0 Grad |
9 | float result = ((float)mess_time / 34.5); |
10 | |
11 | char buf[5]; |
12 | sprintf(buf,"%2.1f\n",result); // format result in string |
13 | SPI_wr2(0x4B); // print temp "xx.xC" |
14 | SPI_wr2(0x5C); |
15 | SPI_wr2(buf[3]+32); |
16 | SPI_wr2(buf[1]+32); |
17 | SPI_wr2(buf[0]+32); |
18 | |
19 | |
20 | |
21 | // heat alert
|
22 | if (result >= 70.0) |
23 | {
|
24 | SPI_wr2(0x22); // overtemp on |
25 | SPI_wr2(0x01); |
26 | SPI_wr2(0x34); |
27 | OCR2B = 255; |
28 | }
|
29 | else if (result < 69) |
30 | {
|
31 | SPI_wr2(0x22); // overtemp off |
32 | SPI_wr2(0x01); |
33 | SPI_wr2(0x10); |
34 | |
35 | int fan_PWM = ((float)(result-29) * 4.5); // Fan "log" cuve |
36 | |
37 | if (result <= 35) |
38 | {
|
39 | fan_PWM = 0; |
40 | }
|
41 | |
42 | if (fan_PWM >= 255) |
43 | {
|
44 | fan_PWM = 255; |
45 | }
|
46 | OCR2B = fan_PWM; |
47 | }
|
48 | mess_time = 0; |
49 | mess_flag = 0; // nächste Messung freigeben |
50 | |
51 | }
|
Gruß Rolf
Rolf D. schrieb: > Ich habe jetzt die Spannungs-, Strom- und Temperaturanzeige programmiert > (siehe Video) und die Sollwertvorgabe auf die kleine Schrift unter Limit und die Ist-Werte auf die große Schrift! https://www.mikrocontroller.net/attachment/102808/IMAG0113.jpg
Ja genauso hab ich mir das vorgestellt :) Nachdem die Sollwertvorgabe eingestellt wurde, werde ich einige Sekunden abwarten und prüfen ob sich die Werte nicht geändert haben und falls nicht dann werden sie ins EEPROM geschrieben.
:
Bearbeitet durch User
Rolf D. schrieb: > Nachdem die Sollwertvorgabe eingestellt wurde, werde ich einige Sekunden > abwarten und prüfen ob sich die Werte nicht geändert haben und falls > nicht dann werden sie ins EEPROM geschrieben. das habe ich auch geade in meiner 328p Kombi mit I2C EEprom gemacht, wenn ich die HG Beleuchtung LCD5110 ändere, man muss nicht sofort schreiben wenn man noch am Einstellen ist.
Mmm.. Gerade gemerkt. Es gibt rechts keine Unterstriche für die Markierung der Dezimalstellen !?
Rolf D. schrieb: > Gerade gemerkt. Es gibt rechts keine Unterstriche für die > Markierung der Dezimalstellen !? sieht so aus, braucht man das? wenn ja stellt man an den großen Ziffern ein und übernimmt es zu der kleinen Anzeige nach der Speicherung!
:
Bearbeitet durch User
Ich habe fast alle Steuercodes für die Anzeigen-Elemente auf dem Display identifizieren können. Eine Liste folgt später. Gruß Rolf
Rolf D. schrieb: > Ich habe fast alle Steuercodes für die Anzeigen-Elemente auf dem Display > identifizieren können. > > Eine Liste folgt später. dann lasse doch mal alle anzeigen
Hallöchen.. Ich habe ein kleines Problem und weis nicht woran es liegen kann. Immer wenn ein Temperaturwert von 45.8 Grad erreicht wird, bekomme ich falsche Spannungs- und Temperaturwerte angezeigt. Ist die Temperatur niedriger oder höher stimmen wieder die Werte. Test Video: https://youtu.be/Wciua-4qkgg Der Counterwert für die Berechnung der Temperatur wird für Testzwecke auf der rechten Seite unter U-Limit und I-Limit angezeigt. Ein Berechnungsfehler in der Temperaturanzeige kann es nicht sein, da ich die Counterwert von 7420 - 7430 für einen Test, als const Variablen vorgegeben und überprüft habe. Hab mal mein Code hochgeladen. Timer-Funktionen im ATmega328 ----------------------------- Timer1a und Timer1b erzeugen 14Bit PWM für die Spannungs- und Stromsteuerung Timer0 ist für die Zeitmessung des AD-Wandlers zuständig Timer2 erzeugt 8Bit PWM für den Fan. INT0 Interrupt wird vom ADC gesteuert wenn Messung beendet Vielleicht weis ja einer von euch einen Rat. Vorab schon mal ein Dankeschön. Gruß Rolf
:
Bearbeitet durch User
Es scheint wohl ein systembedingter Fehler in meiner Software zu sein, denn ich habe noch weitere Stellen gefunden wo die Werte plötzlich verrückt spielen. Bei Counterwert 8190, 7678 und 7424 !?
:
Bearbeitet durch User
8190 = 1FFE 7678 = 1DFE 7424 = 1D00 vermutlich eher 7422 = 1CFE alle enden auf FE schau mal in ISR (TIMER0_OVF_vect), ob Du dort nicht das Flag zurücksetzen musst. Sonst wird die Routine öfters aufgerufen.
Hallo Nachtgespenst. Danke für deinen Tip. In Atmega Handbuch steht folgendes: "Das Bit TOV0 wird gesetzt, wenn in Timer / Counter0 ein Überlauf auftritt. TOV0 wird bei der Ausführung von von der Hardware gelöscht entsprechender Interrupt-Behandlungsvektor. Alternativ wird TOV0 gelöscht, indem eine logische Eins in das Flag geschrieben wird. Wenn der SREG I-Bit, TOIE0 (Timer / Counter0 Overflow Interrupt Enable) und TOV0 sind gesetzt, der Timer / Counter0 Overflow Interrupt ist hingerichtet." Hab das Bit aber trotzdem mal mit TIFR0 |= (1<<TOV0) zurückgesetzt. Leider ohne Erfolg. Die Fehler treten immer an den gleichen Stellen auf. Aber dies ist schon mal ein guter Hinweis von dir. Danke :) Gruß Rolf
:
Bearbeitet durch User
Problem gelöst :) In der Interrupt-Routine für den externen Interrupt_0 (ADW-Pin) hatte ich den Timer_0 gesperrt und das busy_flag für das Messzeitende gesetzt. Das hat vermutlich zu den Problemen mit dem Timer0-Overflow Interrupt geführt und letztendlich zu falschen Zählerwerten. Lösung: Wenn jetzt der externe Interrupt_0 auslöst, wird nur das busy_flag gesetzt. Der Timer_0 wird jetzt außerhalb der Interrupt-Routine gesperrt. Als High-Byte für den 16Bit Zähler habe ich das unbenutzte OCR0B Register im Timer_0 benutzt.
1 | // Timer 0 Overflow interrupt for meassurments
|
2 | ISR (TIMER0_OVF_vect) |
3 | {
|
4 | OCR0B++; |
5 | }
|
6 | |
7 | // interrupt 0 from ADW-Pin
|
8 | ISR(INT0_vect) |
9 | {
|
10 | busy_flag = 1; |
11 | }
|
12 | |
13 | uint16_t start_Measurement(uint8_t mess_ch) |
14 | {
|
15 | // clear ADC
|
16 | PORTC |= (1 << ADC_AD0) | (1 << ADC_AD2); |
17 | PORTC &= ~(1<<ADC_AD1); |
18 | _delay_ms(20); |
19 | |
20 | // set U-Mess measurement
|
21 | if (mess_ch == U_Mess) |
22 | {
|
23 | PORTC &= ~((1 << ADC_AD0) | (1<<ADC_AD1) | (1<<ADC_AD2)); |
24 | _delay_ms(50); |
25 | }
|
26 | |
27 | // set I-Mess measurement
|
28 | if (mess_ch == I_Mess) |
29 | {
|
30 | PORTC &= ~((1 << ADC_AD1) | (1<<ADC_AD2)); |
31 | PORTC |= (1 << ADC_AD0); |
32 | _delay_ms(50); |
33 | }
|
34 | |
35 | // set Temp1 for measurement
|
36 | if (mess_ch == T1_Mess) |
37 | {
|
38 | PORTC &= ~(1<<ADC_AD2); |
39 | PORTC |= (1 << ADC_AD0) | (1<<ADC_AD1); |
40 | _delay_ms(50); |
41 | }
|
42 | |
43 | // set Temp2 for measurement
|
44 | if (mess_ch == T2_Mess) |
45 | {
|
46 | PORTC &= ~((1<<ADC_AD0) | (1<<ADC_AD2)); |
47 | PORTC |= (1<<ADC_AD1); |
48 | _delay_ms(50); |
49 | }
|
50 | |
51 | // start ADC measurment
|
52 | PORTC |= (1 << ADC_AD2); |
53 | PORTC &= ~((1 << ADC_AD0) | (1<<ADC_AD1)); |
54 | |
55 | // set busy for measurement
|
56 | busy_flag = 0; |
57 | |
58 | // clear timer register
|
59 | //counter_h = 0;
|
60 | OCR0B = 0; |
61 | TCNT0 = 0; |
62 | |
63 | |
64 | TIFR0 |= (1<<TOV0); |
65 | |
66 | // Overflow Interrupt erlauben
|
67 | TIMSK0 |= (1<<TOIE0); |
68 | |
69 | // start Timer 0
|
70 | TCCR0B |= (1<<CS00)| (1<<CS01); |
71 | |
72 | // INT0 enabled
|
73 | EIMSK |= (1<<INT0); |
74 | |
75 | // wait until measuring ends
|
76 | while(busy_flag == 0){} |
77 | |
78 | // stop Timer 0
|
79 | TCCR0B &= ~((1<<CS00) | (1<<CS01) | (1<<CS02)); |
80 | |
81 | // read timer value for measurements
|
82 | uint16_t mess_time = ((OCR0B << 8) | TCNT0); |
83 | |
84 | return mess_time; |
85 | }
|
Gruß Rolf
:
Bearbeitet durch User
2.Lösungsversuch Es kann passieren, dass zur fast gleichen Zeit, indem das externen Interrupt-Flag INT0 vom ADW-Pin gesetzt wird, dass Overflow-Flag TOV0 von Timer_0 gesetzt wird und der OCR0-Wert von Timer_0 nicht mehr berücksichtigt wird. Das führt dann zu falschen Messergebnissen. Aus diesem Grund habe nach der Abfrage des ext. Interrupt-Flags INT0 noch eine Abfrage des Overflow-Flags TOV0 von Timer_0 programmiert und den OCR0 Wert inkrementiert wenn das TOV0 Flag gesetzt ist. Code
1 | // init extern Interrupt_0
|
2 | init_Interrupt() |
3 | {
|
4 | EICRA |= (1<<ISC01); // set Int0 to falling edge |
5 | sei(); // enable Global Interrupts |
6 | }
|
7 | |
8 | |
9 | void init_Timer0() |
10 | {
|
11 | // Timer0B konfigurieren
|
12 | TCCR0B |= (1<<CS00) | (1<<CS01); // Prescaler 8 |
13 | }
|
14 | |
15 | |
16 | // Timer2B für Fan PWM konfigurieren
|
17 | void init_Timer2() |
18 | {
|
19 | TCCR2B |= (1<<CS21)|(1<<CS22); // prescaler 64 |
20 | TCCR2A |= (1<<COM2B1) | (1<<WGM21) | (1<<WGM20); // Set OC2B at bottom, clear OC2B |
21 | OCR2B = 255; // 100% Fan-PWM |
22 | GTCCR &= ~(1 << TSM); |
23 | }
|
24 | |
25 | |
26 | // Timer 0 Overflow interrupt for meassurments
|
27 | ISR (TIMER0_OVF_vect) |
28 | {
|
29 | OCR0B++; |
30 | }
|
31 | |
32 | |
33 | uint16_t start_Measurement(uint8_t mess_ch) |
34 | {
|
35 | // clear ADC
|
36 | PORTC |= (1 << ADC_AD0) | (1 << ADC_AD2); |
37 | PORTC &= ~(1<<ADC_AD1); |
38 | _delay_ms(20); |
39 | |
40 | // set U-Mess measurement
|
41 | if (mess_ch == U_Mess) |
42 | {
|
43 | PORTC &= ~((1 << ADC_AD0) | (1<<ADC_AD1) | (1<<ADC_AD2)); |
44 | _delay_ms(50); |
45 | }
|
46 | |
47 | // set I-Mess measurement
|
48 | if (mess_ch == I_Mess) |
49 | {
|
50 | PORTC &= ~((1 << ADC_AD1) | (1<<ADC_AD2)); |
51 | PORTC |= (1 << ADC_AD0); |
52 | _delay_ms(50); |
53 | }
|
54 | |
55 | // set Temp1 for measurement
|
56 | if (mess_ch == T1_Mess) |
57 | {
|
58 | PORTC &= ~(1<<ADC_AD2); |
59 | PORTC |= (1 << ADC_AD0) | (1<<ADC_AD1); |
60 | _delay_ms(50); |
61 | }
|
62 | |
63 | // set Temp2 for measurement
|
64 | if (mess_ch == T2_Mess) |
65 | {
|
66 | PORTC &= ~((1<<ADC_AD0) | (1<<ADC_AD2)); |
67 | PORTC |= (1<<ADC_AD1); |
68 | _delay_ms(50); |
69 | }
|
70 | |
71 | // start ADC measurment
|
72 | PORTC |= (1 << ADC_AD2); |
73 | PORTC &= ~((1 << ADC_AD0) | (1<<ADC_AD1)); |
74 | |
75 | // clear timer register
|
76 | OCR0B = 0; |
77 | TCNT0 = 0; |
78 | |
79 | // Overflow Interrupt erlauben
|
80 | TIMSK0 |= (1<<TOIE0); |
81 | |
82 | // clear Timer_0 overflow_flag
|
83 | TIFR0 |= (1<<TOV0); |
84 | |
85 | // clear extern INT0 Flag
|
86 | EIFR |= (1<<INTF0); |
87 | |
88 | // start Timer 0
|
89 | TCCR0B |= (1<<CS00)| (1<<CS01); |
90 | |
91 | sei(); |
92 | |
93 | // wait until measuring ends
|
94 | while(!(EIFR & (1<<INTF0))); |
95 | |
96 | cli(); |
97 | |
98 | // stop Timer 0
|
99 | TCCR0B &= ~((1<<CS00) | (1<<CS01)); |
100 | |
101 | // Hat wärend des Anhaltens von Timer_0
|
102 | // noch ein Überlauf statt gefunden dann OCR0B inc
|
103 | if(TIFR0 & (1<<TOV0)) |
104 | {
|
105 | OCR0B++; |
106 | }
|
107 | |
108 | // read timer value for measurements
|
109 | uint16_t mess_time = ((OCR0B << 8) | TCNT0); |
110 | |
111 | return mess_time; |
112 | }
|
Gruß Rolf
:
Bearbeitet durch User
Joachim B. schrieb: > Rolf D. schrieb: >> Ich habe fast alle Steuercodes für die Anzeigen-Elemente auf dem Display >> identifizieren können. >> >> Eine Liste folgt später. > > dann lasse doch mal alle anzeigen Wie gewünscht noch einmal alle Elemente auf der Anzeige. LCD Codes im Anhang. Die zwei Steuersignale vom LCD-Controller für das Relais (Trafo-Umschaltung) und Standby-Funktion muss ich noch herausfinden. Sollte aber kein großes Problem sein. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > mit fehlerfreie Temperaturanzeige. OK, mich stört (persönlich nur) dein großes 'C' für Celsius, sieht komisch aus, ich könnte mir vorstellen nur oben die 'C' Segmente als "Kreis" zu schliessen für 45,7° gefühlt sieht das besser aus als 45,7C Zwischen 4 & q (falls das überhaupt möglich ist!) https://www.fontpapa.com/wp-content/uploads/2018/09/d043a33eae4c4fb1a931e7fb7d8c131e.gif
:
Bearbeitet durch User
Ja eigentlich eine gute Idee. Mal schaun ob ich die einzelnen Segmente im LCD Controller ansprechen kann. Ich habe leider kein Datenblatt, was die Ansteuerung wesentlich erleichtern würde. Um zB einzelne Segmente zu finden verwende ich Programmierschleifen und probiere darin Parametergruppen aus. Finde ich Segmente, dann grenze ich die Parameter in der Schleife weiter ein, bis ich die Steuersequenz gefunden habe.
:
Bearbeitet durch User
Rolf D. schrieb: > Ja eigentlich eine gute Idee oh oh, wer eigentlich verwendet.....aber schaun mer mal.... Rolf D. schrieb: > ob ich die einzelnen Segmente > im LCD Controller ansprechen kann
Der LCD Controller ist auf meiner Platine vergossen. Im INet habe ich andere Platinen gesehen und einen Schriftzug von Samsung erkannt. Müsste ein 100poliger Controller Typ so ähnlich wie der KS0073 von Samsung sein. Die Pinbelegung stimmt aber nicht überein.
OK einverstanden, war nur eine Idee, es sah so aus als wenn man an ALLE Segmente rankommt!
Hallöchen.. Rolf D. schrieb: > 2.Lösungsversuch > > Es kann passieren, dass zur fast gleichen Zeit, indem das externen > Interrupt-Flag INT0 vom ADW-Pin gesetzt wird, dass Overflow-Flag TOV0 > von Timer_0 gesetzt wird und der OCR0-Wert von Timer_0 nicht mehr > berücksichtigt wird. Das führt dann zu falschen Messergebnissen. > > Aus diesem Grund habe nach der Abfrage des ext. Interrupt-Flags INT0 > noch eine Abfrage des Overflow-Flags TOV0 von Timer_0 programmiert und > den OCR0 Wert inkrementiert wenn das TOV0 Flag gesetzt ist. Ich habe eine bessere Lösung gefunden um den korrekten OCR0-Wert vom Timer_0 bei einem Interrupt auszulesen. Ist die Integration im AD-Wandler beendet wird durch eine negative Flanke am INT0 Eingang vom Mikrocontroller ein Interrupt ausgelöst (Messzeitende). In der Interrupt-Routine von INT0 wird der Timer_0 durch das setzen der CS00 und CS01 Bits im TCCR0B Register gestoppt. Jetzt kann ich in aller Selen Ruhe und ohne viel Hektik den OCR0 Wert und TCNT0 Wert von Timer_0 auslesen und zu einem 16Bit Messzeitwert zusammen fügen. Code
1 | // Timer 0 Overflow interrupt for meassurments
|
2 | ISR (TIMER0_OVF_vect) |
3 | {
|
4 | OCR0B++; |
5 | }
|
6 | |
7 | |
8 | // interrupt 0 from ADW-Pin
|
9 | ISR(INT0_vect) |
10 | {
|
11 | // stop Timer 0
|
12 | TCCR0B &= ~((1<<CS00) | (1<<CS01)); |
13 | }
|
Gruß Rolf
:
Bearbeitet durch User
> In der Interrupt-Routine von INT0 wird der Timer_0 durch > das setzen der CS00 und CS01 Bits im TCCR0B Register gestoppt. Das Rücksetzen stoppt den Timer (siehe deinen Code-Asusschnitt) :)
Danke für den Hinweis. Ja.. Du hast recht. Kleiner Fehler von mir. Um den Timer_0 zu stoppen, müssen die Bits CS00 und CS01 im TCCR0B Register natürlich gelöscht werden. Noch eine andere Frage zum Timer: Kann man einen Compare Match Interrupt von Timer_0 auslösen wenn der OCR0B-Wert in der TIMER0_OVF Interrupt Routine incrementiert wird. Es geht darum den 16Bit Wert des Timers_0 als Messzeit vorzugeben und nicht die _delay Funktion zu benutzen.
1 | // Timer 0 Overflow interrupt for meassurments
|
2 | ISR (TIMER0_OVF_vect) |
3 | {
|
4 | OCR0B++; |
5 | }
|
:
Bearbeitet durch User
Rolf D. schrieb: > Noch eine andere Frage zum Timer: Kann man einen Compare Match Interrupt > von Timer_0 auslösen wenn der OCR0B-Wert in der TIMER0_OVF Interrupt > Routine incrementiert wird. Ja, kann man. Das System merkt sich den Compare Match und würde ihn direkt danach anspringen.
Ok. Vielen Dank für die Info. Damit wären die _delay() Pausen für die Messungen vermeidbar und ich hätte Zeit um zum Beispiel den Encoder und die Taster abzufragen.
Hallo.. Hier ein grober Ablaufplan der Software (Bild). Das mit dem Compare Match Interrupt von Timer0 war kein guter Lösungsansatz, da dieser nur den 8Bit Wert im Timer0 vergleicht und bei Gleichstand einen Interrupt auslöst. Der Timer0-Überlauf wird dabei nicht berücksichtigt. Ich habe eine andere Lösung gefunden. In der Overflow Interrupt Routine von Timer0 vergleiche ich die Anzahl der Überläufe im OCR0B-Register mit einer Variable und stoppe den Timer0 bei Gleichstand.
1 | // Timer0 Overflow interrupt
|
2 | ISR (TIMER0_OVF_vect) |
3 | {
|
4 | OCR0B++; |
5 | |
6 | if (OCR0B == Time_max) |
7 | {
|
8 | TCCR0B &= ~((1<<CS00) | (1<<CS01)); |
9 | }
|
10 | }
|
:
Bearbeitet durch User
Frage: Weis vielleicht jemand wofür der Regler Anschluss im PPS5330 Netzteil notwendig ist (siehe Bild). Größeres Bild: https://i.ibb.co/B37WYXQ/ELV-Power-02.jpg Im Voraus schon mal vielen Dank für die Hilfe :) Gruß Rolf
:
Bearbeitet durch User
Über diesen Anschluss wird dem Controller signalisiert ob der Spannungs- oder der Stromregler gerade aktiv ist.
Ja super. Danke. Da es sich um einen Komperator-Ausgang (Pin14 an IC4) handelt, kann ich also damit die "Active" Anzeige für Spannung oder Strom im Display steuern. Ist der Pin14 von IC4 +5V so müsste der Strom "Aktive" sein. Ist der Pin14 -5V dann ist die Spannung "Aktive" !?
:
Bearbeitet durch User
Ich habe das gerade mal überprüft. Strombegrenzung im Netzteil auf 100mA eingestellt und den Laststrom auf 200mA. Beim Einschalten der Last sinkt die Spannung von 30V auf 0.36V und der Strom bleibt stabil bei 100mA. Der Pin14 von IC4 wird high.
:
Bearbeitet durch User
Rolf D. schrieb: > Hier ein grober Ablaufplan der Software (Bild). Da ist nen Fehler im Ablaufplan: Wenn die Messphase noch läuft würde ich nach Tastenabfrage und Co nicht vor die U/I/T Messung zurückspringen sondern dahinter einsteigen, vgl. Bild. Ist das wirklich so bei dir umgesetzt? Könnte den ein und anderen Effekt erklären, denk da noch mal über den Ablauf nach ;)
@ Rolf Wie ist der Stand der Software? Wirst du sie veröffentlichen?
Hi Wenn die Software fertig ist dann werde ich sie hier posten. Bin jetzt dabei die Software auf dem Mega88 der im Netzteil verbaut ist anzupassen. Im Moment läuft sie noch auf meinem Nano-Board. Wird aber noch ein Weilchen dauern, da ich gerade mit meinem Fahrrad in Urlaub bin :) Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Wird aber noch ein Weilchen dauern, da ich gerade mit meinem Fahrrad in > Urlaub bin :) Na dann schönen Urlaub und immer ein wenig Rückenwind oder Gefälle auf der Strecke damit es sich leichter tritt. ;-))
Hab jetzt ein Pedelec (siehe hier): https://www.pedelecforum.de/forum/index.php?threads/umbau-eines-trekkingrad-zum-pedelec.79231/ Gruß Rolf
"Entladeschlussspannung bei Silitium-Ionen Akkus bei 2.5V. " Ist das Humor? Klaus.
Hallöchen.. Mein Urlaub ist schon wieder vorbei. Pedelec fahren macht tierisch viel Spaß. Aber jetzt gehts weiter.. Ich habe die Code-Liste für den LCD-Controller noch ein wenig ergänzt. Die Ansteuerung der beiden Port-Pins für das Relais und Standby-Funktion sind jetzt bekannt. Die Spannungseinstellung mit Encoder funktioniert auch schon. Bei der Tastenabfrage gibts noch ein kleines Problem. Da funktioniert das Entprellen noch nicht so richtig. Aber das sollte keine große Problem sein. Werde am Wochenende mal ein Video machen. Bis denn.. Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. Hab mal ein Video gemacht und auf Youtube hochgeladen. Die Probleme mit dem Tasten-Prellen habe ich gelöst. Ferner funktioniert im Menü die Spannungs- und Stromeinstellung schon. Die Werte von Spannungseinstellung und Strombegrenzung stimmen leider noch nicht so ganz mit der Ausgangsspannung überein. Das liegt vermutlich an der falschen Berechnung der Linearisierungskurve. Ich habe mal den Code hochgeladen. Diesen muss ich aber noch optimieren und einige Fehler beseitigen. Der Code läuft z.Zt auf einem ATmwega328 Nano und muss noch für den ATmega88 im PPS5330 angepasst werden. Link zum Video: https://youtu.be/7m1KzoA-EqY
:
Bearbeitet durch User
Rolf D. schrieb: > Hab mal ein Video gemacht und auf Youtube hochgeladen. Die Probleme mit > dem Tasten-Prellen habe ich gelöst was mich wundert du kannst 31,2C anzeigen lassen aber 31,2° nicht? also nur die obersten 4 Segmente vom 'C' geschlossen? würde IMHO besser aussehen
Hallo Joachim.. Ich gebe dir Recht, dass würde besser aussehen. Leider sind nicht alle LCD-Segmente einzeln ansteuerbar. Muss mal schaun ob ich das noch hinbekomme. Gruß Rolf
Rolf D. schrieb: > Leider sind nicht alle > LCD-Segmente einzeln ansteuerbar wie hast du dann das C hinbekommen, ist ja auch keine Zahl!
Ausschnitt aus dem Code für die Display Initialisierung
1 | //*************************************************************************
|
2 | // init LCD
|
3 | //*************************************************************************
|
4 | void init_LCD (void) |
5 | {
|
6 | _delay_ms(1000); |
7 | SPI_wr2(0xF0); // clear LCD |
8 | _delay_ms(100); |
9 | SPI_wr2(0xC1); // LCD-Backlight on |
10 | _delay_ms(100); |
11 | SPI_wr2(0xB0); // Relais off VCC 24.0V |
12 | |
13 | SPI_wr2(0xA1); // Stanby on |
14 | wr_SPI_buffer3(0x22,0x03,0x31); // print "Standby" |
15 | Standby_flag = 1; |
16 | |
17 | wr_SPI_buffer3(0x20,0x05,0x1D); // clear "Aktiv" (V) |
18 | wr_SPI_buffer3(0x27,0x03,0x1D); // clear "Aktiv" (A) |
19 | |
20 | |
21 | print_value(0x43,0); // print " 0.00 V" |
22 | wr_SPI_buffer3(0x23,0x05,0x34); |
23 | wr_SPI_buffer3(0x23,0x06,0x34); |
24 | |
25 | print_value(0x47,0); // print "0.000 A" |
26 | wr_SPI_buffer3(0x27,0x03,0x31); |
27 | wr_SPI_buffer3(0x27,0x01,0x34); |
28 | |
29 | print_value(0x4B,0); // print "0.00 C" |
30 | wr_SPI_buffer3(0x23,0x02,0x31); |
31 | |
32 | print_value(0x63,0); // print "0.00 V" (V-Limit) |
33 | wr_SPI_buffer3(0x00,0x23,0x38); // print "x.xx" (Punkt) |
34 | wr_SPI_buffer3(0x04,0x20,0x38); // print "U-Limit" |
35 | wr_SPI_buffer3(0x04,0x21,0x38); // print "V" |
36 | |
37 | print_value(0x67,0); // print "0.000 I" (I-Limit) |
38 | wr_SPI_buffer3(0x04,0x27,0x34); // print "x.xxx" (Punkt) |
39 | wr_SPI_buffer3(0x23,0x05,0x31); // print "I-Limit" |
40 | wr_SPI_buffer3(0x27,0x05,0x31); // print "A" |
41 | }
|
Gruß Rolf
Rolf D. schrieb: > print_value(0x4B,0); // print "0.00 C" > wr_SPI_buffer3(0x23,0x02,0x31); scheint mir wie eine Command Übertragung zu sein da hilft es nur wohl mal testweise als äussere Schleife alle print_value(0x00,0); bis print_value(0xFF,0); laufen zu lassen und als 3 innere Schleifen von wr_SPI_buffer3(0x00,0x00,0x00); bis wr_SPI_buffer3(0xFF,0xFF,0xFF); wenn dann irgendwann das '°' auftaucht weisst du es
Ja. So ähnlich habe ich die einzelnen Segmente analysiert. Wie gesagt. Man kann leider nicht jedes LCD-Segment direkt ansteuern. Mit einem kleinen Trick konnte ich das Grad Symbol doch noch realisieren. Dazu musste ich auf die entsprechende Position im Display eine "2" schreiben und zwei Segmente löschen sowie ein Segment setzen (siehe Bild). Das Grad Symbol muss beim Aktualisieren des Temperaturwertes immer wieder neu geschrieben werden, da es von dem 4stelligen Anzeigewert im LCD-Controller überschrieben wird. Macht aber nix, denn die Übertragung ist super schnell.
1 | //*************************************************************************
|
2 | // print T1_measurement result
|
3 | //*************************************************************************
|
4 | void print_T1_result(uint16_t mess_time) |
5 | {
|
6 | if (mess_time <= 5845) { |
7 | mess_time = 5845; |
8 | }
|
9 | |
10 | mess_time -= 5845; // = offset bei 0.0 Grad |
11 | |
12 | float result = ((float)mess_time / 34.5); |
13 | |
14 | //--------------------------------------------------------------------
|
15 | char buf[4]; |
16 | sprintf(buf,"%2.1f\n",result); // format result in string |
17 | SPI_wr2(0x4B); // print temp "xx.x" |
18 | SPI_wr2(0x52); // 4.Digit (Platzhalter für Grad symbol) |
19 | SPI_wr2(buf[3]+32); |
20 | SPI_wr2(buf[1]+32); |
21 | SPI_wr2(buf[0]+32); |
22 | |
23 | // print Degrees symbol
|
24 | wr_SPI_buffer3(0x23,0x02,0x31); |
25 | wr_SPI_buffer3(0x30,0x17,0x20); |
26 | wr_SPI_buffer3(0x30,0x26,0x38); |
27 | wr_SPI_buffer3(0x30,0x24,0x17); |
28 | |
29 | // heat alert
|
30 | if (result >= 75) |
31 | {
|
32 | SPI_wr2(0xA1); // Stanby on |
33 | SPI_wr2(0x22); // set "Standby" |
34 | SPI_wr2(0x03); |
35 | SPI_wr2(0x31); |
36 | Standby_flag = 1; |
37 | return; |
38 | }
|
39 | else if (result >= 70.0) |
40 | {
|
41 | SPI_wr2(0x22); // overtemp on |
42 | SPI_wr2(0x01); |
43 | SPI_wr2(0x34); |
44 | OCR2B = 255; // set max Fan PWM |
45 | return; |
46 | }
|
47 | else if (result < 69) |
48 | {
|
49 | SPI_wr2(0x22); // overtemp off |
50 | SPI_wr2(0x01); |
51 | SPI_wr2(0x11); |
52 | |
53 | if (result <= 35) |
54 | {
|
55 | OCR2B = 20; // set min Fan PWM |
56 | }
|
57 | else
|
58 | {
|
59 | uint8_t fan_speed = ((result-31) * 5.0); // calc fan_speed |
60 | OCR2B = fan_speed; |
61 | }
|
62 | }
|
63 | }
|
:
Bearbeitet durch User
Rolf D. schrieb: > Kleines Preview von mir mit falsch eingebauter Reflektorscheibe: > Youtube-Video "ELV PPS 5330" Jetzt müsstest du nur noch erzählen, was du da rumdrückst.
Rolf D. schrieb: > Ja. So ähnlich habe ich die einzelnen Segmente analysiert. > > Wie gesagt. Man kann leider nicht jedes LCD-Segment direkt ansteuern. > Mit einem kleinen Trick konnte ich das Grad Symbol doch noch > realisieren. Dazu musste ich auf die entsprechende Position im Display > eine "2" schreiben und zwei Segmente löschen sowie ein Segment setzen > (siehe Bild). gefällt mir, auf jeden Fall besser als das 'C'
Im Video: Das Gerät oberhalb des Netzteils ist eine Elektronische Last. Hab das nur um den Laststrom für das Netzteil einzustellen und die Spannung zu kontrollieren. Wie gesagt. Die Spannungswerte stimmen noch nicht ganz. Beim Strom sieht es aber schon ganz gut aus :) Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. Ich bin gerade dabei meinen Programm Code etwas zu verkleinern, damit er in den Flash des ATmega88 passt. Aus diesem Grund habe ich die meisten LCD Kommandos in Tabellen im Programmspeicher hinterlegt. Leider klappt der Tabellenzugriff per send_LCD_commands(Standby_on) Funktion nicht. Hab da irgendwie Problemchen mit Pointern und Zeiger. Im Voraus schon mal vielen Dank für eure Unterstützung. Gruß Rolf Programm Code
1 | //Command tables
|
2 | const uint8_t clr_Digit_Lines[] PROGMEM = {0x24,0x07,0x1D,0x24,0x06,0x15, |
3 | 0x24,0x06,0x1D,0x24,0x05,0x15,0x27,0x01,0x1D,0x27,0x01,0x15,0x27,0x02, |
4 | 0x1D,0x27,0x02,0x15}; |
5 | |
6 | const uint8_t Standby_on[] PROGMEM = {0xA1,0x22,0x03,0x31,0x20,0x05, |
7 | 0x1D,0x27,0x03,0x1D}; |
8 | |
9 | const uint8_t Standby_off[] PROGMEM = {0xA0,0x22,0x03,0x1E,0x20,0x05,0x32, |
10 | 0x27,0x03,0x1D}; |
11 | |
12 | |
13 | //*************************************************************************
|
14 | // send LCD commands
|
15 | //*************************************************************************
|
16 | void send_LCD_commands (const int * Com_Adr) |
17 | {
|
18 | for (uint8_t i = 0; i < 10; i++) |
19 | {
|
20 | SPI_wr2(pgm_read_byte (Com_Adr + i)); |
21 | }
|
22 | }
|
23 | |
24 | |
25 | Funktionsaufruf im Programm |
26 | |
27 | send_LCD_commands(Standby_on); |
:
Bearbeitet durch User
Hallöchen.. Ich habe den Programmcode jetzt soweit optimiert und liege mit 7964 Bytes knapp unter der Programmspeichergrenze von 8192 Bytes des ATmega88 (siehe Code). Was ich noch optimieren könnte, wäre einige Fließkomma-Berechnung für die Ist- und Soll-Werte auf Festkomma-Berechnung mit Integer-Zahlen umzustellen. Ferne die prinf-Funktion für die String-Umwandlung zu vermeiden. Das kostet bekanntlich immer viel Speicherplatz im Flash. Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. Hab jetzt die ganzen Fließkommaberechnungen entfernt und auf Festkommaarithmetik mit Integerzahlen umgestellt. Ferner habe ich alle printf Anweisungen entfernt und auf eine eigene Ausgabefunktion umgestellt. Der Artikel "Festkommaarithmetik" hier auf Mikrocontroller.net war mir eine große Hilfe. So konnte ich die Code-Größe im Flash auf 7054 Byte kürzen. Link: https://www.mikrocontroller.net/articles/Festkommaarithmetik Was noch fehlt ist das Speichern und Aufrufen von Sollwert-Vorgaben mit der Recall-Taste und die Anpassung an den Mega88 im Netzteil. Im Anhang der Quellcode. Gruß Rolf
:
Bearbeitet durch User
Wie lang ist das kompilierte Programm jetzt? Anregung. Alle magischen Zahlen (Konstanten) durch sprechende Bezeichner/defines ersetzen (gegebenenfalls mit Kommentar).
1 | uint16_t Value = (((uint32_t)(521 * Usoll) * 100) / 100950); |
Danke für den Tip! Die Programmlänge beträgt 7162 Bytes im Flash und 28 Byte im SRAM. Ich programmiere mit Atmel Studio 7.0 und habe die Compiler Optimierung auf "Os" stehen. Ein kleines Problem ist die Linearisierung der Ausgangsspannung. Die stimmt noch nicht so ganz. Die Abweichung beträgt bei Vorgabe von 1.00V = 1.09V und bei 30.00V = 29.81V. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Ein kleines Problem ist die Linearisierung der Ausgangsspannung. Die > stimmt noch nicht so ganz. Die Abweichung beträgt bei Vorgabe von 1.00V > = 1.09V und bei 30.00V = 29.81V. hast du Steigung m und Offset b berechnet? ich rechne das immer aus mit 2 Wertepaare in y/x du weisst doch noch aus dem Mathematikunterricht: y = m * x + b und mit y1 = m * x1 + b und y2 = m * x2 + b kannst du m & b ermitteln natürlich gibt es da immer noch Unlinearitäten und du kannst die Intervalle auch verkleinern und mehrere nutzen.
:
Bearbeitet durch User
Hallo Joachim Vielen Dank. Mit Mathe tuh ich mich allerdings immer etwas schwer. Aber ich denke das werde ich noch hinbekommen :) Gruß Rolf
Rolf D. schrieb: > Aber > ich denke das werde ich noch hinbekommen :) wenn du noch Hilfe brauchst melde dich der Weg sollte klar sein, am ADC in eine Spannung einstellen vom Labornetzteil oder Poti Spannung1 messen und notieren adc Wert1 notieren Spannung2 messen und notieren adc Wert2 notieren m = dy/dx mit x = adc Wert und y = Spannung weil ja immer x der unabhängige Wert ist und y der Abhängige ist somit ergibt sich y = m * x + b automatisch.
:
Bearbeitet durch User
Hallo Joachim.. Bräuchte doch etwas Hilfestellung von Dir. In der Berechnung treten leider Fehler auf. Bei Vorgabe von 1.000mV stimmt der Wert annähernd. Aber bei kleineren oder größeren Werten leider nicht. Was mache ich falsch ? Die Usoll Vorgabe ist in mV.
1 | //*************************************************************************
|
2 | // set Usoll
|
3 | //*************************************************************************
|
4 | void set_Usoll (int32_t Usoll) // Usoll in mV |
5 | {
|
6 | Usoll = 1000; // Test! Usoll in mV |
7 | |
8 | // offset = 5
|
9 | // 539 = 1.000mV
|
10 | // 5210 = 10.000mV
|
11 | // 10395 = 20.000mV
|
12 | // 15580 = 30.000mV
|
13 | |
14 | |
15 | |
16 | uint16_t m = 0; |
17 | uint8_t b = 5; |
18 | uint16_t x1 = 539; |
19 | uint16_t y1 = 1000; |
20 | uint16_t x2 = 15580; |
21 | uint16_t y2 = 30000; |
22 | |
23 | m = ((uint32_t)Usoll / 539); |
24 | |
25 | uint16_t y = ((uint32_t)m * 539 + b); |
26 | |
27 | OCR1A = (y); |
28 | }
|
:
Bearbeitet durch User
m ist delta y / delta x also m = (y1 - y2) / (x1 - x2) https://de.wikipedia.org/wiki/Geradengleichung und in der Nähe 0 ist JEDES Messgerät unsauber! Gilt für alle ADC (auch in DMM) oder analoge Meßgeräte! also besser den Wert m aus der möglichst besten Geraden nehmen wenn du mit den Fehlern im unteren Bereich nicht leben kannst, dann erstelle eine Tabelle für die unteren ADC Wert = x.xxx mV oder generiere die für jeden ADC Bereich von bis eigene m und b
:
Bearbeitet durch User
Du könntest interpolieren und für bestimmte Bereiche mit anderen Faktoren arbeiten.
Ich habe das jetzt wie folgt gemacht. Ich habe Usoll auf 30.00V eingestellt und eine Ausgangsspannung von 30.16V gemessen. Der errechnete Steigungsfaktor wäre (30160mV / 30000mV) = 1.0053.
1 | //*************************************************************************
|
2 | // set Usoll
|
3 | //*************************************************************************
|
4 | void set_Usoll (int32_t Usoll) // Usoll in mV |
5 | {
|
6 | const uint8_t offset = 38; |
7 | |
8 | // OCR1A 539 = 1.000mV
|
9 | // OCR1A 5210 = 10.000mV
|
10 | // OCR1A 10395 = 20.000mV
|
11 | // OCR1A 15580 = 30.000mV
|
12 | |
13 | // m = (30160mV / 30000mV) = (1 / 1.0053) = 0.9947 Fließkomma
|
14 | // m = (30160mV / 30000mV) = (1.0053 * 10000) = 10053 Festkomma
|
15 | |
16 | uint16_t m = 10053; |
17 | |
18 | //uint16_t y = ((uint32_t)521 * Usoll / 1000); // ohne Linearisierung
|
19 | //uint16_t y = (((uint32_t)521 * Usoll / 1000) * m); // mit Linearisierung (Fließkomma)
|
20 | uint16_t y = (((uint32_t)(521 * Usoll) * 10) / m); // mit Linearisierung (Festkomma) |
21 | |
22 | OCR1A = (y + offset); |
23 | }
|
:
Bearbeitet durch User
Rolf D. schrieb: > Ich habe das jetzt wie folgt gemacht. Ich habe Usoll auf 30.00V > eingestellt und eine Ausgangsspannung von 30.16V gemessen. Der > errechnete Steigungsfaktor wäre (30160mV / 30000mV) = 1.0053. du hast es leider immer noch nicht verstanden du musst 2 Wertepaare (=4 Werte) erstellen! wie oft soll ich das noch posten? Joachim B. schrieb: > m = (y1 - y2) / (x1 - x2) also 2 Spannungen und dazu passend 2 ADC Werte! und natürlich nicht so nah beieinander es muss schon möglichst viel vom Messbereich erfassen der in der Geraden liegt, den Link zu Wiki hatte ich auch schon gezeigt https://de.wikipedia.org/wiki/Geradengleichung und wenn das nicht hilft https://wiki.zum.de/wiki/Geraden es sind immer Wertepaare 2 x und dazu gehörig 2 y Du wirst auch feststellen das bei 0V der ADC nicht 0 ist, was am Offset liegt und an der Nichtlinearität um NULL
:
Bearbeitet durch User
Joachim B. schrieb: > wie oft soll ich das noch posten? Mindestens noch zweimal. Nur dadurch ist die erforderliche Linearität gewährleistet.
Danke für deine Geduld :) Mein Problem ist der fehlende OCR1A Wert in der Berechnung ? Diesen Wert muss erst kennen !? Die Funktion übergibt für die Berechnung nur einen Usoll Wert in mV. Daraus muss ich einen OCR Wert für den PWM-Ausgang berechnen der dann die Ausgangsspannung steuert. Gruß Rolf
:
Bearbeitet durch User
Beitrag #6389383 wurde vom Autor gelöscht.
Beitrag #6389385 wurde vom Autor gelöscht.
Hallöchen.. Die Software Portierung vom externen ATmega328 Nano Board auf den im Netzteil sitzenden ATmega88 Mikrocontroller hat problemlos funktioniert. Für weitere Softwareänderungen habe ich eine Verbindungsleitung für einen ISP-Programmer an die Platine gelötet. Die Anschlüsse dafür waren ja schon vorhanden. Nächster Schritt ist das Programmieren einer Abgleichfunktion (Setup-Menü) für die Ausgangsspannung und Strom. Diesbezüglich hat mir Joachim aus dem Forum eine sehr gute Hilfestellung gegeben. Ferner fehlt noch die Memory Funktion für die Sollwertvorgaben für Spannung und Strom. Ich denke, das sollte noch in den Flash-Speicher passen. Aktuell ist noch ca. 1.4KB frei. Gruß Rolf
:
Bearbeitet durch User
Hier noch einmal der Anschlussplan für den ISP Programmer am PPS5330. Gruß Rolf
Habe zwei Fragen zu deinem interessanten Projekt. - Konntest du die Originalfirmware auslesen und sichern? - Ist es (einfach) möglich den 88er auszulöten und durch einen 328er zu ersetzen?
Hallo Melchior.. Die Original Firmware konnte ich leider nicht auslesen. Durch einen Fehler meinerseits habe ich die Firmware versehentlich gelöscht. Der ATmega88 hat die gleiche Anschlussbelegung wie der ATmega328. Gruß Rolf
Joachim B. schrieb: > m ist delta y / delta x > > also m = (y1 - y2) / (x1 - x2) > > https://de.wikipedia.org/wiki/Geradengleichung Idee zum Abgleich per Software: 1. Um in das Abgleich-Menü zu gelangen müssen beide Pfeiltasten gleichzeitig 2s lang gedrückt werden. 2. Das Abgleich-Menü zeigt 1.00V an. Automatisch wird der 1.Spannungswert (y1) und der 1.OCR-Wert (x1) gespeichert. 3. Mit dem Dehgeber (Encoder) wird jetzt die Ausgangsspannung auf 1.00V genau eingestellt. 4. Mit der Enter-Taste wird der 2.Spannungwert (y2) und 2.OCR-Wert (x2) gespeichert. Damit hätte ich für die Berechnung m = (y1 - y2) / (x1 - x2) die entsprechenden Werte. Das ganze kann man dann noch für eine 2.Spannung zB 27V machen. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Idee zum Abgleich per Software: OK ich bin gespannt ob und wie es ausgeht! drücke dir die Daumen für "akzeptable geringe Fehler"
:
Bearbeitet durch User
Hallo Rolf, der Fixpoint-Artikel ist viel zu dezimallastig. Man muss wie der µC binär denken, also z.B. nicht mit 100, sondern mit 128 oder 256, nicht mit 1000, sondern mit 1024 rechnen, das sind nur ein paar shifts. Statt dividieren lieber mit dem Kehrwert multiplizieren. Sauberes Projekt, vielen Dank!
Danke für die Tips. Muss die Berechnung in der Praxis erst einmal hinbekommen. Dann sehn wir weiter ;)
eProfi schrieb: > Hallo Rolf, der Fixpoint-Artikel ist viel zu dezimallastig. > Man muss wie der µC binär denken, also z.B. nicht mit 100, sondern mit > 128 oder 256, nicht mit 1000, sondern mit 1024 rechnen, das sind nur ein > paar shifts. Statt dividieren lieber mit dem Kehrwert multiplizieren. > > Sauberes Projekt, vielen Dank! Also etwa so:
1 | int32_t a,b; |
2 | |
3 | a = b / 0.5432; // direkte Formel, Division durch Konstante |
4 | // mit Fließkommaarithmetik
|
5 | a = b * 1,8409; // Multiplikation mit 1/x |
6 | // mit Fließkommaarithmetik
|
7 | a = b * 18409 / 10000; // Umformung in Kehrwert und Festkommaarthimetik |
8 | // mit Zehnerpotenzen
|
9 | a = b * 15081 / 8192; // Festkommaarithmetik mit Zweierpotenzen. |
10 | a = (b * 15081) >> 13; // Division explizit ausgeführt als Schiebeoperation |
11 | // für nicht so schlaue Compiler
|
gut erkannt, z.B. so:
1 | void set_Usoll (int32_t Usoll){ |
2 | #define Digi_offset 43 // Offset 0.00V
|
3 | #define counts_per_10v 5161
|
4 | #define u_factor (0.5 + counts_per_10v * 65536 / 10000) //33823.6296
|
5 | OCR1A = Digi_offset + ((Usoll * u_factor) >> 16); |
6 | //43+30000*33823/65536=15525.940673
|
7 | }
|
8 | |
9 | //*************************************************************************
|
10 | // set Isoll
|
11 | //*************************************************************************
|
12 | void set_Isoll (int Isoll){ |
13 | const uint32_t i_factor = 0.5+530/100*65536; //347341.3 |
14 | OCR1B = (Isoll * i_factor) >> 16; |
15 | }
|
Syntax nicht überprüft
hier muss man aufpassen, dass der Compiler nicht 5 * 65536 = 327680 ausrechnet, weil er 530 / 100 = 5 rechnet: 0.5+530/100*65536 Lieber (uint32_t)(0.5+530.0/100.0*65536) statt #define counts_per_10v 5161 #define u_factor (0.5 + counts_per_10v * 65536 / 10000) //33823.6296 ginge auch #define counts_per_30v 15483 #define u_factor (0.5 + counts_per_30v * 65536 / 30000) //33823.6296
eProfi schrieb: > hier muss man aufpassen, dass der Compiler nicht 5 * 65536 = 327680 > ausrechnet, weil er 530 / 100 = 5 rechnet: > 0.5+530/100*65536 > Lieber (uint32_t)(0.5+530.0/100.0*65536) > > statt > #define counts_per_10v 5161 > #define u_factor (0.5 + counts_per_10v * 65536 / 10000) //33823.6296 > ginge auch > #define counts_per_30v 15483 > #define u_factor (0.5 + counts_per_30v * 65536 / 30000) //33823.6296 So funktioniert es. Ich hab den Digit_offset und die counts_per_30v noch etwas anpassen müssen. Den u_factor habe ich von #define in eine 32bit integer Variable umgestellt. Spart einiges an Speicherplatz im Flash.
1 | //*************************************************************************
|
2 | // set Usoll (0 - 30.000mV)
|
3 | //*************************************************************************
|
4 | void set_Usoll (uint16_t Usoll) |
5 | {
|
6 | #define Digi_offset 133
|
7 | #define counts_per_30v 15406
|
8 | #define Umax 30000
|
9 | uint32_t u_factor = (0.5 + counts_per_30v * 65536 / Umax); |
10 | OCR1A = Digi_offset + (((uint32_t)Usoll * u_factor) >> 16); |
11 | }
|
Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Den u_factor habe ich von #define in eine 32bit > integer Variable umgestellt. Spart einiges an Speicherplatz im Flash. und den 328p einlöten magst du nicht? :) wie sind denn nun die aktuellen Werte m & b für ADV und mV ist es dir gerade genug?
:
Bearbeitet durch User
Hallo Joachim.. Ein Austausch des ATmega88 ist aus meiner Sicht nicht erforderlich, da ich im Flash noch 1.8 KB freien Speicher habe. Das sollte für die Abgleich- und Memory-Funktion ausreichen. Zur Zeit belegt das Programm 6304 Byte im Flash. Der Vorschlag von eProfil funktioniert in so fern, weil ich den Wert für counts_per_30v 15406 manuell ermittelt habe. Also ohne berechneten Abgleich. Die Abgleich-Funktion programmiere ich gerade. Wofür steht eigentlich die 0.5 in der Berechnung. Wenn ich die weglasse, dann ändert sich am Ergebnis nichts.
1 | uint32_t u_factor = (0.5 + counts_per_30v * 65536 / Umax); |
Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Wofür steht eigentlich die 0.5 in der Berechnung. Wenn ich die weglasse, > dann ändert sich am Ergebnis nichts. ist eine pfiffige Aufrundung, wie wir in der Schule lernten, alles gleich oder über 0,5 wird aufgerundet, unter eben abgerundet. Wenn natürlich der Wert 0,4 ist ist ändert sich nichts, ist der Wert gleich oder über 0,5 wird auf die nächste gradzahlige aufgerundet! Rolf D. schrieb: > (0.5 + counts_per_30v * 65536 / Umax) macht schon per #define der Preprocessor Rolf D. schrieb: > uint32_t u_factor = (0.5 + counts_per_30v * 65536 / Umax); mit uint32_t wird dann das Rechenergebnis als INT eingesetzt sonst würde alles was 0.5 hat zu Fliesskomma im Code übersetzt und vorbei wäre es mit dem Verzicht auf floating point Berechnung!
:
Bearbeitet durch User
> ist eine pfiffige Aufrundung, wie wir in der Schule lernten, > alles gleich oder über 0,5 wird aufgerundet, unter eben abgerundet. Ohne das 0.5 würde er die Nachkommastellen nur abschneiden. Damit das funktioniert, muss der Präprozessor aber Float rechnen, dazu eine der Konstanten in der Multiplikation als Float angeben, oder (float) davorschreiben, das habe ich vergessen. Die Berechnung im µC findet dennoch platzsparend in Integern statt. Man könnte auch bei der Berechnung noch runden: OCR1A = Digi_offset + (((uint32_t)Usoll * u_factor) >> 16); ---> OCR1A = Digi_offset + (((uint32_t)Usoll * u_factor) >> 16) + (((uint32_t)Usoll * u_factor) >> 15) & 1; Zum Speicherplatz: wollten wir nicht noch eine USB / Serielle spendieren, damit man das Gerät zum Erstellen von Messreihen an einen PC hängen kann? Wenn das auch noch im 88er Platz haben soll, müssen wir evtl. weiter "entschlacken". Da sehe ich noch Potential ;-) Was spricht dagegen, den Nano drinzulassen? Dann hat man gleich die Schnittstelle dran.
Habe noch eine andere Idee ausprobiert. Die Ausgangsspannung wird mit der Soll-Spannung verglichen und automatisch abgeglichen.
1 | //*************************************************************************
|
2 | // set Usoll (0 - 30.000mV)
|
3 | //*************************************************************************
|
4 | void set_Usoll (uint16_t Usoll) |
5 | {
|
6 | #define Digi_offset 133
|
7 | #define Umax 30000
|
8 | static uint32_t counts_per_30v = 15406; |
9 | |
10 | uint32_t u_factor = (0.5 + counts_per_30v * 65536 / Umax); |
11 | OCR1A = Digi_offset + (((uint32_t)Usoll * u_factor) >> 16); |
12 | |
13 | // automatic adjustment
|
14 | if (Usoll < Ulimit) |
15 | {
|
16 | counts_per_30v++; |
17 | }
|
18 | else if (Usoll > Ulimit) |
19 | {
|
20 | counts_per_30v--; |
21 | }
|
22 | }
|
Das Ganze funktioniert Millivolt genau :)
:
Bearbeitet durch User
1 | OCR1A = Digi_offset + (((uint32_t)Usoll * u_factor) >> 16) + |
2 | (((uint32_t)Usoll * u_factor) >> 15) & 1; |
Da stimmt was nicht. Das Ergebnis ist immer 0 ? Hab mal ein Video gemacht: https://youtu.be/_QoG5D6Xaf8 Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Das Ganze funktioniert Millivolt genau :) Rolf D. schrieb: > Da stimmt was nicht. Das Ergebnis ist immer 0 ? ja was denn nun, so kommen wir nicht weiter und man soll auch nicht "plenken" Du postest viel aber immer zu knapp, wer der nicht deine Gedanken kennt soll dir folgen, stelle dir einfach vor du zeigst deine letzten 2 beiden Postings jemand anderen, glaubst du er weiss wovon die Rede ist?
Ja.. Du hast da vielleicht Recht. In der Ruhe liegt die Karft ;) Was bedeutet "plenken" ?
:
Bearbeitet durch User
Rolf D. schrieb: > Du hast da vielleicht Recht wieso vielleicht? an welcher Stelle in meinem Post könnte ich unrecht haben?
Joachim B. schrieb: > Du postest viel aber immer zu knapp, wer der nicht deine Gedanken kennt > soll dir folgen, stelle dir einfach vor du zeigst deine letzten 2 beiden > Postings jemand anderen, glaubst du er weiss wovon die Rede ist? Ich meine diesen Beitrag.
:
Bearbeitet durch User
Rolf D. schrieb: > Auf das hier. ja und wo ist MEIN Fehler auf dem ich nur vielleicht Recht habe? was ja impliziert das ich doch nicht Recht habe.
Ich trink jetzt mal ein Käffchen und schau mir Alles in Ruhe noch mal an :) Was bedeutet denn jetz "plenken" ? Übrigens.. Nachmals vielen Dank für deine gute Ünterstützung und Tipps. Das gleiche gilt auch für die anderen User hier aus dem Forum. Man lernt doch nie aus ;) Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Was bedeutet denn jetz "plenken" ? findet man auch wo anders > Übrigens.. Nachmals vielen Dank für deine gute Ünterstützung und Tipps. und ich kassiere wie immer darauf MINUS, oh man das Bewertungssystem ist echt sooo bescheuert, aber viel Feind, viel Ehr! OK ich sollte alles NEGATIVE stets nur noch invertieren
Rolf D. schrieb: > Was bedeutet "plenken" ? Ein Leerzeichen vor einem Satzzeichen nennt man 'Plenken'. Dein Projekt finde ich übrigens spannend. Die ELV-Hardware wäre eine interessante Grundlage für einen Eigen(nach)bau eines Labornetzteils. Bei Netzteilen ist es ja ein bisschen wie mit Geld: Wann hat man schon zu viel davon? @Joachim Etwas mehr Konzilianz würde evtl. weniger Minüsse nach sich ziehen...
Erwin E. schrieb: > @Joachim > Etwas mehr Konzilianz würde evtl. weniger Minüsse nach sich ziehen.. ich bin konziliant, nur wenn ich als Doofi hingestellt und ignoriert werde juckt es mich gelegentlich schon! siehe...ach egal! Rolf D. schrieb: > Ja.. Du hast da vielleicht Recht. ich habe Recht, nicht nur vielleicht! und hier? Beitrag "Re: einfache USB-Fernbedienung" IRMP ist geil, auch ohne 433MHz Empfänger weil es nur Software ist die auch ohne 433MHz Empfänger arbeitet. Da kann man schon mal aus der Haut fahren! Joachim B. schrieb: > Du postest viel aber immer zu knapp, zu dem stehe ich absolut und muss man wirklich "plenken" hier erfragen und beantworten? Kann ein TO nicht mal selber nachschauen? Warum sind wir hier schon bei 160 Beiträge? Warum stehen alle notwendigen Infos so verteilt? oder dieser Thread Beitrag "ESP32 Dev Kit Betriebsspannung" warum wird über die Eingangsspannung diskutiert, 12V hat der Regler so verbaut mit dem Strom und der Leistung nicht verkraftet!
:
Bearbeitet durch User
Erwin E. schrieb: > Dein Projekt finde ich übrigens spannend. Sehe ich genauso und schaue deshalb hin & wieder rein. > @Joachim > Etwas mehr Konzilianz ... Ist immer anzuraten. Hier ist ein ruhiger Thread und so sollte es auch bleiben.
> OCR1A = Digi_offset + (((uint32_t)Usoll * u_factor) >> 16) + > (((uint32_t)Usoll * u_factor) >> 15) & 1; Da brauchen wir noch mehr Klammern, und das (uint32_t) kann weg: OCR1A = Digi_offset + ((Usoll * u_factor) >> 16) + (((Usoll * u_factor) >> 15) & 1); Die Idee ist genau wie oben: das um 15 nach rechts geschobene Bit hat die Wertigkeit 0,5. Wenn das gesetzt ist, addieren wir noch eine Eins "das Bit eben" dazu. Evtl. kann es schneller sein, das Bit direkt abzufragen: merk32 = Usoll * u_factor; round8 = ((uint16_t)(merk32) & 0x8000)?1:0; OCR1A = Digi_offset + (uint16_t)(merk32 >> 16) + round8; Ich würde ja die 32-Bit-Variablen als Struct definieren und auf die einzelnen Bytes direkt zugreifen, auch weil wir ja nie 32x32-Bit-Multiplikationen brauchen. Für 16x16-->32 Mult braucht man nur 4 Bytes miteinander multiplizieren. So ähnlich wie ich es hier gemacht habe: Beitrag "Rechnen mit AVR" Ich weiß nicht, welcher Compiler so schlau ist und das berücksichtigt.
eProfi schrieb: > Ich weiß nicht, welcher Compiler so schlau ist bis jetzt konnte man den GCC eigentlich vertrauen, aber natürlich kann man mit pure ASM noch einiges rausholen, fragt mal c-hater :) Ich frage mich manchmal auch warum immer alle Register auf den Stacl gesichert werden obwohl ich vielleicht gerade keine nun davon nutze, aber ich bin ja nicht so tief im System und musste mich bis jetzt nie mehr auf ASM Ebene begeben, früher (TM) musste man öfter als Platz noch knapper war und Compiler mies waren.
Hallöchen.. Da bin ich wieder :) Meine sportliche Übung für Heute ist geschafft (45KM Rad gefahren). Mit 60 muss man was für die Figur tun ;) Danke für das Interesse an meinem Projekt. Ich bemühe mich immer wieder, ein Thema interessant zu gestalten. Ab und an geraten die Dinge bei mir mal etwas durcheinander, weil man viele Infos bekommt und es gleich ausprobieren möchte. Aber aus Problemen und Lösungen lerne ich immer wieder und vielleicht hat es für den Einen oder Anderen auch etwas geistigen Nährwert. Martin schrieb: > Hier ist ein ruhiger Thread und so sollte es auch bleiben. Ich bin ein friedlicher und ruhiger Mensch ;) Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. Neuer Tag, neues Problem :( Das Problem ist eine kleine Messwertschwankung, wenn ich den Encoder oder die Tasten betätige. In der Regel dürfte das nicht auftreten, da die Messwerterfassung durch einen (TIMER2_OVF_vect) Interrupt und in der 4.Messphase durch den externen (PCINT0_vect) Interrupt gesteuert wird. Encoder und Tasten werden in einer Schleife im Hauptprogramm abgefragt. Ich habe die Messwerterfassung in 4 Phasen gegliedert. 1.Phase (löschen des ADC Integrators) Das Flag "Timer2_run_flag" auf 1 setzen. Den Timer2 initialisieren und starten. Mit dem löschen des ADC integrators beginnen. Zurück zum Hauptprogramm springen und Encoder und Tasten abfragen. 2.Phase (ADC Integrator aufladen) Wenn das "Timer2_run_flag" nach Ablauf der Entladezeit (OCR2B) durch den (TIMER2_OVF_vect) Interrupt auf 0 gesetzt wurde, dann den Timer2 neu initialisieren und das "Timer2_run_flag" auf 1 setzen. Timer2 starten und mit dem Aufladen des ADC integrators beginnen. Zurück zum Hauptprogramm springen und Encoder und Tasten abfragen. 3.Phase (ADC Integrator entladen und Zeit messen) Wenn "Timer2_run_flag" durch den (TIMER2_OVF_vect) Interrupt auf 0 gesetzt wurde, dann den Timer2 neu initialisieren und das "Timer2_run_flag" und "ADW_flag" auf 1 setzen. Jetzt mit dem Entladen des ADC integrators beginnen. Zurück zum Hauptprogramm springen und Encoder und Tasten abfragen. 4.Phase (Messwerte anzeigen) Wenn das "Timer2_run_flag" durch den (PCINT0_vect) Interruppt auf 0 gesetzt wird, dann aktuellen Messwert zB Volt, Ampere oder Temperatur anzeigen. Danach Flags und Messphase löschen. Zurück zum Hauptprogramm springen und Encoder und Tasten abfragen. Im Anhang das Programm. Leider bin ich noch nicht dahinter gekommen, was die Ursache für die Messwertschwankung sein könnte. Die Benutzung der Timer ist wie folgt. Timer0 steuert am OCR0A Ausgang den Fan. Timer1 steuert an seinen Ausgängen OCR1A und OCR1B die 14Bit PWM für Spannung und Strom. Timer2 ist für die Messwerterfassung zuständig. Die delay_ms() Funktion aus der Library habe ich nicht benutzt, weil ich mir nicht sicher bin, ob sie einen Timer benutzt. Gruß Rolf
:
Bearbeitet durch User
Hallöchen.. Die Ursache ist vermutlich die Wartezeit zwischen den einzelnen Mess-Phase und das Umschalten des ADC-Muxers IC6. Da es durch die Tastatur und Encoder Abfragen im Hauptprogramm zu kleinen Zeitverzögerungen beim Umschalten der Mess-Phasen kommen kann, wird keine genaue Integrationszeit des ADC-Integrators erreicht. Um zu verhinder, dass der Integrationskondensator C49 nach einem Timer2 Interrupt sich weiter auflädt oder entlädt, habe ich jetzt den ADC-Muxer in den Interrupt Routinen gesperrt.
1 | //*************************************************************************
|
2 | // Timer2 Overflow interrupt for measurement results
|
3 | //*************************************************************************
|
4 | ISR (TIMER2_OVF_vect) |
5 | {
|
6 | OCR2B++; |
7 | |
8 | if (OCR2B == 48 && ADW_flag == 0){ |
9 | TCCR2B &= ~((1<<CS00) | (1<<CS01)); // stopp timer and disabled ADC |
10 | PORTD |= ((1 << ADC_AD0) | (1<<ADC_AD1) | (1<<ADC_AD2)); |
11 | Timer2_run_flag = 0; |
12 | }
|
13 | }
|
14 | |
15 | //*************************************************************************
|
16 | // Meassurement interrupt from ADW-Pin
|
17 | //*************************************************************************
|
18 | ISR(PCINT0_vect) |
19 | {
|
20 | // fallende Flanke
|
21 | if (!(PINB & (1<<PB0))) { |
22 | TCCR2B &= ~((1<<CS00) | (1<<CS01)); // stopp timer and disabled ADC |
23 | PORTD |= ((1 << ADC_AD0) | (1<<ADC_AD1) | (1<<ADC_AD2)); |
24 | Timer2_run_flag = 0; |
25 | }
|
26 | }
|
Gruß Rolf
:
Bearbeitet durch User
Der LCD-Controller könnte ein S3C72P9 sein: https://datasheet.iiic.cc/datasheets-1/samsung_semiconductor_division/S3P72P9-QX.pdf The S3C72P9 single-chip CMOS microcontroller has been designed for high performance using Samsung's newest 4-bit CPU core, SAM47 (Samsung Arrangeable Microcontrollers). With an up-to-896-dot LCD direct drive capability, flexible 8-bit and 16-bit timer/counters, and serial I/O interface, the S3C72P9 offers an excellent design solution for a wide variety of applications which require LCD functions. Up to 39 pins of the 100-pin QFP package can be dedicated to I/O. Eight vectored interrupts provide fast response to internal and external events. In addition, the S3C72P9's advanced CMOS technology provides for low power consumption and a wide operating voltage range. The S3C72P9 is made by shrinking the KS57C21516. The S3C72P9 is comparable to KS57C21516, both in function and in pin configuration except that S3C72P9 have a 32,768 ×8-bit ROM, 1056×4-bit RAM, 12 common selectable and LCD contrast control function. OTP The S3C72P9 microcontroller is also available in OTP (One Time Programmable) version, S3P72P9. S3P72P9 microcontroller has an on-chip 32K-byte one-time-programmable EPROM instead of masked ROM. The S3P72P9 is comparable to S3C72P9, both in function and in pin configuration. Er hat zwar "EPROM read protection", aber man könnte versuchen, ihn auszulesen. Aber wer will das disassemblieren? Danke Rolf für Dein Durchhaltevermögen.
Hallo eProfi Danke für den Link. Wie gut das ich am Anfang eine Teilanalyse der seriellen Daten vom ATmega88 zum LCD Controller gemacht habe. Das hat mir bei der Softwareentwicklung für das Netzteil viel Zeit erspart. Sonst hätte ich mich zusätzlich noch mit der Programmierung eines LCD Controllers beschäftigen müsse. Zur Zeit entwickel ich noch eine Kalibrier Funktion für die Spannungs- und Strommessung. Ferner ist mir aufgefallen, dass die Spannung bei steigender Temperatur etwas sinkt. Messung unter Belastung von 30V/A3. Bis 30'C ist alles stabil. Bei 70'C und 10 minütiger Belastung habe ich eine Abweichung von -0,2V am Ausgang festgestellt. Das muss ich dann auch noch irgendwie kalibrieren. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Zur Zeit entwickel ich noch eine Kalibrier Funktion für die Spannungs- > und Strommessung. Ferner ist mir aufgefallen, dass die Spannung bei > steigender Temperatur etwas sinkt. wie sehen jetzt die Wertepaare aus? (mV/ADC)
Hallo Joachim Ich habe jetzt zwei Werte Gruppen ermittelt. Der Digitale Offset ist bei allen gleich. Digital offset = 133 y1 = 1.0007V x1 = 512 counts + offset y2 = 30.001V x2 = 15419 counts + offset y1 = 5.0010V x1 = 2567 counts + offset Y2 = 27.004V x2 = 13878 counts + offset
:
Bearbeitet durch User
Hallöchen.. Zum Vergleich mit dem PPS5330 Netzteil habe ich ein anderes Labornetzteil (SPD3303X von Siglent) getestet. Ich habe das Siglent Netzteil eingeschaltet und die Spannung auf 1.000V eingestellt. Die unbelastete Ausgangsspannung hatte nach dem Einschalten eine Spannung von 1.0011V. Nach 20 Minuten hat sich die Ausgangsspannung auf 0.9985V stabilisiert (1.Bild). Danach habe ich die Spannung auf 30.000V eingestellt und 20 Minuten lang mit 3A belastet. Die Ausgangsspannung sank kurz nach dem Teststart von 30.003V auf 29.971V und stabilisierte sich dann wieder auf 29.975V (2.Bild). Das gleiche Szenario habe ich dann mit dem PPS5330 Netzteil durchgeführt. Die unbelastete Ausgangsspannung sank nach 20 Minuten unwesentlich von 1.0016V auf 1.0014V (3.Bild). Unter Belastung sank die Ausgangsspannung aber merklich. Innerhalb von 20 Minuten von 30.003V auf 29.837V (4.Bild). Die Temperatur am Kühlkörper stieg mit offenem Gehäuse während des 20minütigen Tests von 27'C auf über 46'C an. Der Test hat gezeigt, dass im Vergleich zum Siglent Netzteil, die Ausgangsspannung des PPS5330 Netzteils unter sehr hoher Belastung und bei steigender Temperatur nicht stabil ist. Das muss ich dann in der Software anhand der ausgelesenen Temperaturwerte kompensieren. Leider fehlt mir da der direkte Vergleich mit der Original Software und den Messwerten. Mit meinem Multimeter (UNI-T UT181A) habe ich die Messwerte protokolliert. Das Multimeter habe ich 20 Minuten vor der Messung eingeschaltet. Es hat eine DC Ungenauigkeit von <0.025% und 60000 counts. Gruß Rolf
Rolf D. schrieb: > Der Digitale Offset ist bei > allen gleich. dann hast du es offensichtlich richtig gemacht und meine Erklärung gut umsetzen können, das freut mich. War doch nicht so schwer oder? Rolf D. schrieb: > die > Ausgangsspannung des PPS5330 Netzteils unter sehr hoher Belastung und > bei steigender Temperatur nicht stabil ist. das bekommst du auch noch hin, kannst ja Kennlinien aufnehmen und sogar die Kennlinienverschiebung mit der Temperatur berücksichtigen, also m und b zu einer Temperatur ermitteln.
:
Bearbeitet durch User
Hallo Joachim Ja Danke. Den Spannungsverlust bei hohen Temperaturen will ich noch kompensieren. Dann bin ich fast fertig. Gruß Rolf
Rolf D. schrieb: > Hallo Joachim geht doch, trotz einiger Störfeuer und Mißtöne in der Zwischenzeit.
Beitrag #6395160 wurde vom Autor gelöscht.
Hallöchen.. Ich habe ein kleines Video gedreht um die Auflösung und Genauigkeit der Ausgangspannung im PPS5330 Netzteil zu demonstrieren. Der eingebaute AD-Wandler hat eine Auflösung von 14Bit. Macht bei 30.00V eine maximale Auflösung von 1.8mV. Link: https://youtu.be/ACEmlj7E1N0
Rolf D. schrieb: > Hallöchen.. > > Ich habe ein kleines Video gedreht um die Auflösung und Genauigkeit der > Ausgangspannung im PPS5330 Netzteil zu demonstrieren. Spannend bis zum Ende. Der Hauptdarsteller erweist sich als Könner in seinem Fach und auch der Regisseur hatte eine Sternstunde. Wann ist Kino-Premiere? 😀
Hallöchen.. Danke. Aber ein wenig ist noch zu tun. Die Temperaturkompensation muss ich noch programmiere und das Speichern und Abrufen der Sollwerte im EEPROM. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > muss > ich noch programmiere und das Speichern und Abrufen der Sollwerte im > EEPROM. echt? wie oft willst du speichern? Ein Konzept damit das EEPROM länger hält? Im Zweifel würde ich ja ein FRAM wählen, oder ein I2C EEPROM im DIL Sockel zum leichter tauschen!
Die Sollwert-Vorgaben werden mit der Taste "Memory" im 512 Byte großen EEPROM des Atmega88 gespeichert. Das Aufrufen der gespeicherten Sollwert-Vorgaben erfolgt mit der Taste „Recall“ und dem Encoder für die Auswahl der Programm-Nummer. Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Die Sollwert-Vorgaben werden mit der Taste "Memory" im 512 Byte großen > EEPROM des Atmega88 gespeichert. wie oft? ich würde ja sowas o.ä. wählen https://www.adafruit.com/product/1895
:
Bearbeitet durch User
Das EEPROM im ATmega88 lässt sich 10.000 mal beschreiben. Insgesammt stehen 16 Speicherplätze für Sollwert-Vorgaben zur Verfügung. Das Abspeichern der aktuell eingestellten Sollwert für Spannung und Strom erfolgt mit der Taste „Memory“ durch den Benutzer. Das Aufrufen von Sollwert-Vorgaben erfolgt mit der Taste „Recall“. Die Speicherplatz-Nummer kann mit dem Encoder ausgewählt werden. Mit "Enter" werden die Vorgaben übernommen. Gruß Rolf
Rolf D. schrieb: > Das Abspeichern der aktuell eingestellten Sollwert für Spannung und > Strom erfolgt mit der Taste „Memory“ durch den Benutzer. OK dann könnte das reichen, aber trotzdem sind mir EEPROMs zum Speichern von veränderlichen Daten mittlerweile unsympatisch weil endlich! Rolf D. schrieb: > Das EEPROM im ATmega88 lässt sich 10.000 mal beschreiben war das nicht ein eingelötetes SMD? also nicht mal Tausch leicht möglich?
Ja. Im Netzteil sitzt ein ATmega88 als 32 TQFP Bauform. Mit einer Heißluftpistole lässt sich der Chip aber leicht auslöten und ersetzen.
Die Temperaturkompensation im Netzteil funktioniert jetzt. Muss das aber im Code noch etwas nachbessern. Das Ganze ist etwas zahlenlastig aber es funktioniert. Ein Video dazu gibts später. Nebenbei: Ein neues spannendes Projekt steht auch schon in den Startlöchern. Es ist ein DIY Synth mit Teeny 4.0 Board im Shruthi Gewand mit 16Bit Sound echten Wafetables und analogen Filtern. Werde hier im Forum drüber berichten. Gruß Rolf
:
Bearbeitet durch User
Ich habe jetzt extra wegen dieses Threads ein solches gebrauchtes Gerät gekauft und werde berichten, ob die original-Software die Temperaturkompensation macht. Dann kann man sich auch auf die Suche nach der Ursache begeben. Außerdem will ich den genauen Zusammenhang DAC-Wert-Ausgangsspannung analysieren. Und bei Deinen Sythi-Projekten lese ich ebenfalls sehr interessiert mit. Danke dafür!
eProfi schrieb: > Ich habe jetzt extra wegen dieses Threads ein solches gebrauchtes Gerät > gekauft und werde berichten, ob die original-Software die > Temperaturkompensation macht. dann wäre evtl. hilfreich: Rolf D. schrieb: > Ich habe eine Bitte. Durch einen dummen Fehler am SPI Port des ATmega88 > habe ich die Firmware des PPS 5330 geschrottet. Das Auslesen des > ATmega88 mit einem DIAMEX ALL AVR Programmer funktioniert zwar, aber das > Hexfile binhaltet nur Datenmüll (siehe Anhang). Kann mir vielleicht > jemand helfen ? Melchior schrieb: > - Konntest du die Originalfirmware auslesen und sichern?
Fehlt eigentlich nur noch eine PC-Schnittstelle am Netzteil, damit es auch als PC-programmierbares Netzteil einsetzbar ist. -branadic-
branadic schrieb: > Fehlt eigentlich nur noch eine PC-Schnittstelle am Netzteil auch das wäre leicht nachzurüsten, mit Tausch des ATmega88p zu 328p ist auch reichlich mehr Platz vorhanden Rolf D. schrieb: > Ja. Im Netzteil sitzt ein ATmega88 als 32 TQFP Bauform. Mit einer > Heißluftpistole lässt sich der Chip aber leicht auslöten und ersetzen. meint der TO
eProfi schrieb: > Ich habe jetzt extra wegen dieses Threads ein solches gebrauchtes Gerät > gekauft und werde berichten, ob die original-Software die > Temperaturkompensation macht. > Dann kann man sich auch auf die Suche nach der Ursache begeben. > Außerdem will ich den genauen Zusammenhang DAC-Wert-Ausgangsspannung > analysieren. > Und bei Deinen Sythi-Projekten lese ich ebenfalls sehr interessiert mit. > Danke dafür! Ja das ist eine gute Idee. Vielleicht kannst du auch den Programmcode auslesen. Ich habe das am Anfang leider vermasselt :( Zur Temperaturschwankung: Die Referenzspannung für den ADC wird in der Schaltung durch einen LM385 2.5V erzeugt. Laut Datenblatt hat dieser Baustein eine Toleranz von +- 0.8% (+- 20mV).
:
Bearbeitet durch User
branadic schrieb: > Fehlt eigentlich nur noch eine PC-Schnittstelle am Netzteil, damit es > auch als PC-programmierbares Netzteil einsetzbar ist. > > -branadic- Für diese Funktion muss dann aber ein größerer Mikrocontroller größerem Flash und mit mehr IO-Leitungen verwendet werden. Am ATmega88 im Netzteil sind leider alle Leitungen belegt. Und die 8KB Flash sind schon sehr knapp bemessen.
:
Bearbeitet durch User
Rolf D. schrieb: > eProfi schrieb: >> Ich habe jetzt extra wegen dieses Threads ein solches gebrauchtes Gerät >> gekauft und werde berichten, ob die original-Software die >> Temperaturkompensation macht. >> Dann kann man sich auch auf die Suche nach der Ursache begeben. >> Außerdem will ich den genauen Zusammenhang DAC-Wert-Ausgangsspannung >> analysieren. >> Und bei Deinen Sythi-Projekten lese ich ebenfalls sehr interessiert mit. >> Danke dafür! > > Ja das ist eine gute Idee. Vielleicht kannst du auch den Programmcode > auslesen. Ich habe das am Anfang leider vermasselt :( > > Zur Temperaturschwankung: Die Referenzspannung für den ADC wird in der > Schaltung durch einen LM385 2.5V erzeugt. Laut Datenblatt hat dieser > Baustein eine Toleranz von +- 0.8% (+- 20mV). Siehe Schaltbild
Rolf D. schrieb: > Zur Temperaturschwankung: Die Referenzspannung für den ADC wird in der > Schaltung durch einen LM385 2.5V erzeugt. Laut Datenblatt hat dieser > Baustein eine Toleranz von +- 0.8% (+- 20mV). Ob der LM385 alleine für das Absinken der Ausgangsspannung bei hohen Temperaturen verantwortlich ist, kann ich nicht mit Sicherheit sagen. Der SMD Baustaustein sitzt vorne am rechten Rand auf der Rückseite der Netzteil Platine (siehe Bild).
Rolf D. schrieb: > Siehe Schaltbild es ist wirklich traurig, 3 Beiträge innerhalb einer Stunde! 07.09.2020 15:36 07.09.2020 15:48 07.09.2020 15:52 Das bläht den Thread nur unnötig auf! Nur falls du es noch nicht weisst, innerhalb einer Stunde ohne andere Antworten dazwischen kann man seinen eigenen Beitrag noch editieren! Falls du Angst hast das dann die letzte Antwort keiner mitbekommt dann geht das so: Letzen Beitrag Text kopieren in einen Texteditor! Letzen Beitrag löschen Dann Letzen Beitrag (ehemals vorletzter Beitrag) Text kopieren in den Editor passend davor einsortieren! Letzen Beitrag löschen usw. bis zum letzten deiner Beiträge, einen neuen Beitrag erstellen, alle bekommen Bescheid und alles steht in einem Beitrag! mal ehrlich 194 Beiträge für nichts was es nicht auch in 100 gepasst hätte! Meine Hochachtung für deine Tätigkeit hast du, aber nicht für die Forennutzung
:
Bearbeitet durch User
Rolf D. schrieb: > Rolf D. schrieb: >> Zur Temperaturschwankung: Die Referenzspannung für den ADC wird in der >> Schaltung durch einen LM385 2.5V erzeugt. Laut Datenblatt hat dieser >> Baustein eine Toleranz von +- 0.8% (+- 20mV). > > Ob der LM385 alleine für das Absinken der Ausgangsspannung bei hohen > Temperaturen verantwortlich ist, kann ich nicht mit Sicherheit sagen. > Der SMD Baustaustein sitzt vorne am rechten Rand auf der Rückseite der > Netzteil Platine (siehe Bild). Ein Bild ergänzt.
Würde man auf Basis des ELV-Netzteils eine eigene Variante bauen, wäre es dann vorteilhaft, für die ADC und DAC fertige, integrierte Wandler einzusetzten? Oder sind die Wandler wie sie ELV hier nutzt, für den Zweck 'gut genug'? Der Preis für 'richtige' DAC/ADC würde beim Selbstbau, anders als beim Seriengerät, schließlich keine große Rolle spielen.
Joachim B. schrieb: > Nur falls du es noch nicht weisst, innerhalb einer Stunde ohne andere > Antworten dazwischen kann man seinen eigenen Beitrag noch editieren! Ja.. Das ist mein Problem ;)
Erwin E. schrieb: > Würde man auf Basis des ELV-Netzteils eine eigene Variante bauen, wäre > es dann vorteilhaft, für die ADC und DAC fertige, integrierte Wandler > einzusetzten? Oder sind die Wandler wie sie ELV hier nutzt, für den > Zweck 'gut genug'? > Der Preis für 'richtige' DAC/ADC würde beim Selbstbau, anders als beim > Seriengerät, schließlich keine große Rolle spielen. Bei 16Bit könnte man die Ausgangspannung auf ein mV genau einstellen. Das ist mit dem 14Bit Wandler und der PWM Ansteuerung im PPS5330 Netzteil leider nicht möglich. Auflösung bei 16Bit: 30V/65536 = 0,00045V Auflösung bei 14Bit: 30V/16384 = 0,00183V Gruß Rolf
:
Bearbeitet durch User
Rolf D. schrieb: > Ja.. Das ist mein Problem ;) lesen könnte helfen: Joachim B. schrieb: > Nur falls du es noch nicht weisst, innerhalb einer Stunde ohne andere > Antworten dazwischen kann man seinen eigenen Beitrag noch editieren! > > Falls du Angst hast das dann die letzte Antwort keiner mitbekommt dann > geht das so: > > Letzen Beitrag Text kopieren in einen Texteditor! > Letzen Beitrag löschen > Dann > Letzen Beitrag (ehemals vorletzter Beitrag) Text kopieren in den Editor > passend davor einsortieren! > Letzen Beitrag löschen > > usw. > bis zum letzten deiner Beiträge, > > einen neuen Beitrag erstellen, alle bekommen Bescheid und alles steht in > einem Beitrag!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.