Hallo zusammen, Tutorien habe ich gelesen und auch schon ein paar Sachen ausprobiert. Leider bisher kein Ergebnis. Ich baue für meinen Bachelor ein Gerät, welches über Fotodioden das Umgebungslicht misst und entsprchend eine High Power LED ansteuert um einen relativen Wert der Helligkeit zu halten. Dabei wird der Wert der Fotodiode analog eingelesen und für die weitere Berechnung von 10 auf 8 bit reduziert. Im weiteren Vorgang wird der eingelesene Wert mit dem realtiven Wert (dient als Vorgabe, ist ein poti analog eingelesen) verglichen. Bei einer Abweichung größer/kleiner +-5 Soll meine PWM Zykluszeit der LED solange angepasst werden bis die Abweichung zwischen Soll und ist im Bereich von -2 bis 2 liegt. Die Werte 5 und hier sind hier gewählt um eine Softwarehystere zu gewährleisten und somit ein Flackern der Helligkeit zu vermeiden. Leider ist der bisherige Code nicht in der Lage die Ansteuerung zu gewährleisten, bzw. ich nicht in der Lage den Fehler zu erkennen. Grundlegen funktioniert die Steuerung, wenn ich den Softwarecode so setze, dass er ohne Hystere die Helligkeit anhebt oder senkt, je nach Sollwert und Umgebungslicht. Ich gehe daher davon aus, dass ich irgendwas in der Rechnung falsch geschrieben habe, so einfach sie auch ist. Möglicher Weise auch ein Fehler in der Denkweise und dem Umgang mit Variablen bzw. deren Größe? Vielen Dank an alle die sich die Mühe machen hier mal rein zu schauen im Voraus Felix
Zusatz: Es handelt sich bei der berechnung um pwm_calc in der sub-datei code.c
Hallo, wenn ich es richtig gesehen habe, dann hast du die Variablen in den Funktionen wie z.B. brightness_value nicht global definiert, bzw. übergibst sie den Funktionen nicht. Damit sind es in den Funktionen nur lokale Variablen, die keinen Wert enthalten. Gruß Kai
Hi
Ehrlich gesagt, wenn man so etwas
>ISR(INT0_vect) {//Start interrupt on PCINT1 Vector Routine
pwm_on = 0; //PWM set to 0%
PORTB |= (1<<flash_out);//Activate pull up (provides 5V for the flash
_delay_ms(100); //Watit 50ms
^^^^^^^^^^^^^^
PORTB &= ~(1<<flash_out); //Activate Pull down
} //END Interrupt Routine
in einer Interruptroutine sieht verliert man die Lust weiter zu lesen.
MfG Spess
Ich hab keine Lust mir den C-Code anzuschauen, wenn du nicht mal deine Aufgabenstellung im Klartext formulieren kannst. - Umgebungslicht mit Fotodiode messen. OK - Entsprechend eine High Power LED ansteuern? Warum? Soll die irgendwo das Umgebungslicht nachbilden? Wie wird deren Lichtaussendung erfasst? Wie ist "entsprechend" definiert? Soll das Umgebungslicht davon beeinflusst werden? - Was ist der eingelesene Wert? - ? - ?? Wenn schon der Klartext so unverständlich ist, GRUSELT es mich vor dem C-Code!
>in einer Interruptroutine sieht verliert man die Lust weiter zu lesen.
Ich hör bei sowas sofort auf weiter zu lesen:
#include "variables.c"
#include "interrupt_code.c"
#include "code.c"
diff_brightness = pd_value - brightness_value; Da würfelst Du verschiedene Datentypen zusammen, ich denke Du mußt da Casten.
Hallo, danke für die ersten vernünftigen Rückmeldungen. Ich werde gleich mal testen, was mir aufgezeigt wurde und gebe dan Rückmeldung. Zu den Herren die "Keine Lust ahben" weiterzulesen. Entweder ein Konstruktoven beitrag für mich, jemanden der zugegebn viel zu wenig über C und die Programmierung weiß und nach Hilfe sucht - Oder oben das meist rote X benutzen. Aber nur dumm herumsülzen frisst lediglich Speicher im µC-Server. Was gefällt euch denn nicht? Wie macht man es richtig? Erwin schrieb: > - Entsprechend eine High Power LED ansteuern? > Warum? > Soll die irgendwo das Umgebungslicht nachbilden? > Wie wird deren Lichtaussendung erfasst? > Wie ist "entsprechend" definiert? > Soll das Umgebungslicht davon beeinflusst werden? Die LED ist auf das von der Fotodiode erfasste Messfeld ausgerichtet und soll bei Änderung des Umgebungslichts nachregeln, um das zu beleuchtene Objekt weiterhin mit der selben Intensität zu beleuchten. Das soll zu Video und Fotografie-zwecken genutzt werden (nicht professionell :) ) Die "entsprechende" Ansteuerung meint eine Erhöhung oder Absenkung der Beleuchtung durch die LED. Hierfür wird ein PWM Duty-cycle geändert (0-255). Diese Änderung beeinflusst über einen analogen Schaltkreis den Strom, welcher durch die LED fließt. Die lED Helligkeit ist somit regelbar
>Was gefällt euch denn nicht? > adc_setting &= ~0xFF; //enables ADC0 > pd_value = (adc_byte2 | (adc_byte1 << 8))/4; //write ADC0 value into pd >value byte. PD 10° Dein ADC arbeitet überhaupt nicht.
holger schrieb: >> adc_setting &= ~0xFF; //enables ADC0 >> pd_value = (adc_byte2 | (adc_byte1 << 8))/4; //write ADC0 value into pd >value > byte. PD 10° > > Dein ADC arbeitet überhaupt nicht. Das Datenblatt sagt, dass ADC0 via Adresse 0000 00 angepsorchen wird. Die beiden restlichen Bits auf Position 6 und7 werden ebenfalls mit 0 deklariert und daher aktiviert das Löschen mit 0xFF ADC0. Oder habe ich das falsch verstanden?
>Die beiden restlichen Bits auf Position 6 und7 werden ebenfalls mit 0 >deklariert und daher aktiviert das Löschen mit 0xFF ADC0. Oder habe ich >das falsch verstanden? Das schaltet den Multiplexer auf ADC0. Eine ADC Wandlung wird dadurch aber nicht gestartet. Ausserdem benötigt der ADC eine gewisse Zeit für die Wandlung. Du wartest aber nicht darauf. Deine ADC Routinen funktionieren also nicht. Sieh dir das Datenblatt noch mal an wie man das macht.
Aber wenn ich das ADC result direkt als Wert für die PWM Steuerung nehme, lässt sich dies regeln. Da ich allerdings nicht auf eine Wandlung warte gehe ich mal davon aus, dass es aus Prozesssicht um veraltete ADC Werte handelt?! Kann man das so betrachten? PS: Danke für den Hinweis!
Wahsinn, ist das kompliziert gemacht. Nimmt man die ADC Routinen aus dem AVR-gcc-Tutorial als Grundlage, dann würde ein vernünftiger erster Code (ohne die ADC Routinen) vielleicht 20 bis 30 Zeilen lang sein.
1 | ...
|
2 | |
3 | int main() |
4 | {
|
5 | uint16_t Brightness = 0; |
6 | |
7 | .... Timer 0 aufsetzen für PWM, mittels OCR0 wird die Helligkeit |
8 | .... eingestellt. Größere OCR Werte -> mehr Helligkeit. |
9 | |
10 | ADC_init(); |
11 | |
12 | while( 1 ) |
13 | {
|
14 | Brightness = ADC_Read( 0 ); |
15 | |
16 | if( Brigthness < Limit && OCR0 < 255 ) |
17 | OCR0++; |
18 | else if( Brightness > Limit && OCR0 > 0 ) |
19 | OCR0--; |
20 | |
21 | delay_ms( 100 ); // gib der PWM etwas Zeit, damit ein neuer |
22 | // Wert auch realisiert wird und die Helligkeit
|
23 | // sich auch wirklich ändert, ehe das nächste mal
|
24 | // gemessen wird.
|
25 | }
|
26 | }
|
und das wars dann im Prinzip auch schon und man kann auf einen Blick sehen, wie es funktioniert ohne sich erst mal in 300 Dateien durch 8000 Funktionen zu quälen und nachzusehen, wo wieder mal auf eine der vielen Variablen falsch zugegriffen wird.
:
Bearbeitet durch User
Also, ich habe den tag über ausprobiert, gelesen und getestet. Grundlegend funktioniert das programm soweit, dass es eigenständig die helligkeit der LED steigen oder fallen lässt, abhängig vom Input der Photodiode an ADC0. (Der ADC ist als freilaufend definiert und aktiviert eine neue Messung nach Abluss einer Messung) Soweit sogut, das konnte mein erstes, wohl kompliziertes Programm aber auch. Das neue, etwas überschaubarer geschriebene, Programm läuft sowit bis ich eine Softwarehysterese per while-Schleife einsetze. Die Schaltung steuert sowit auf, dass die Photodiode 5V (bzw. deutlich mehr, Eingang geschützt durch Z-Diode) also am ADC 255 erzeugt. Das PWM signal ist dabei auch bei 100%. Ich hätte hier erwartet, dass das Programm vielelicht um die 128 (ADC Wert) schwankt und nicht aus der while-Schleife herauskommt, aber nicht das es bis 255 läuft und dort stagniert. Wieder mal falsch gedacht?
Ich denke das zweite while ersezten durch if. Innerhalb des while (Brightness != 128){} wird "Brightness" nicht mehr mit den neuen Werten eingelesen.
Des Rätsel Lösung doch so einfach! Habe in die While Schleife eingefügt, dass Brightness neu eingelesen wird. Läuft 1a. Ansonsten hätte ich mit dem if die Hysterese nicht mehr. Vielen Besten Dank!
und wieder die kompliziertest mögliche Lösung. kopfschüttel
1 | while(1){ |
2 | Brightness = (adc_byte2 | (adc_byte1 << 8))/4; |
3 | |
4 | if (Brightness < Limit - 1 && OCR0B < 255) |
5 | {
|
6 | OCR0B++; |
7 | }
|
8 | |
9 | else if (Brightness > Limit + 1 && OCR0B > 0) |
10 | {
|
11 | OCR0B--; |
12 | }
|
13 | |
14 | _delay_ms(250); |
15 | } //end while |
16 | }
|
(Deine Kommentare kannst du in der Pfeife rauchen. Neben ein OCR0B++ brauchst du nicht "increase OCR0B" hinschreiben. Das da OCR0B erhöht wird, das kann ein Blindenhund aus 5 Meter Entfernung erkennen. Kommentare, die nur das wiedergeben, was sowieso schon im Code steht, sind nutzlose Kommentare. Wenn ich dein Betreuer wäre, ich würde dich glatt durchfallen lassen und dann kannst du dir deinen Bachelor sonstwo suchen. Das was du hier ablieferst, das ist erstes, maximal zweites Semester. Aber nicht auf dem Mindestniveau eines Abschlusses, für den dann auch noch ein akademischer Grad vergeben wird. Aber was weiß ich, vielleicht machst du ja auch deinen Bachelor in Politikwissenschaften. Dafür wärs wieder nicht so schlecht, obwohl 95% alle Gymnasiasten, die in ihrer Freizeit programmieren, Besseres abliefern.
:
Bearbeitet durch User
holger schrieb: >>in einer Interruptroutine sieht verliert man die Lust weiter zu lesen. > > Ich hör bei sowas sofort auf weiter zu lesen: > > #include "variables.c" > #include "interrupt_code.c" > #include "code.c" Geht anscheinend schon. Das wird von Assemblerprogrammierern so gemacht. Allerdings fuer C - Holzweg. Also allzu schwer ist es wirklich nicht, .H Dateien zu verwenden. Da schreibst du einfach den Funktionskopf hinein und ein Semikolon. Ich hab mir dass mal angeschaut, und es ist ein ziemlicher Graus. Hier nur ein paar Anhaltspunkte: -Int Funktionen, Rueckgabewert wird nie ausgewertet. -variables.c, wird mehrfach eingebunden, dass duerfte meines Wissens nach garnicht kompilierbar serin. Unterfunktionen brauchst du eigentlich unter 2 Seiten nicht, ausserdem, wenn dass Hauptprogramm kleiner als 10 Seiten ist, auch keine extra Dateien. Wenn du dich an allgemeine Programmierstandards haelst, werden sich andere sich auch zumuten koennen sich es anzuschauen. Die Interrupt routine ist meiner Meinung nach auch falsch, das Interrupt flag wird weder getestet noch zurueckgesetzt. Vielleicht geht das ja bei AVR automatisch? Also dass du Variables.c mehrfach einbinden kannst wundert mich schon. Gibts nicht mindestens eine Warnung? Mit so einem Programm bekommst du eine Abwertung auch wenn es funktioniert wegen schlechtem Programmierstil. Wiegesagt, wenn es nur ein paar Seiten sind, alles in eine Datei.
Takao K. schrieb: > Die Interrupt routine ist meiner Meinung nach auch falsch, das Interrupt > flag wird weder getestet noch zurueckgesetzt. Braucht er auch nicht. > Vielleicht geht das ja bei > AVR automatisch? Tut es > Also dass du Variables.c mehrfach einbinden kannst > wundert mich schon. Gibts nicht mindestens eine Warnung? Das ist eine gcc Eigenart, das der Linker Mehrfachdefinitionen kommentarlos zusammenführt.
Hallo zusammen, zu aller erst vielen Dank für die weiterführenden Kommentare. In der Tat, wie man auch sehen kann, habe ich von C und der Programmierung keine Ahnung. Mein Supervisor ist ebenfalls sehr Hardwarelastig und gibt an selbst gar nicht programmieren zu können. Es geht hier eigentlich auch nicht darum in welch feinen und vllt viel einfachereren Stil ich programmiere, dann würde ich mich nämlich im IT Sektor aufhalten. Des weiteren Schreibe ich Kommentare teilweise auch für Leute die nicht programmieren können. Das 95% aller Hobyyprogrammierer besser sind als ich ist mir auch klar, aber genauso laufen 90% der Jüngeren schneller als ich und ich behaupte einfach mal, dass ich auch wesentlich besser im Barren turnen kann als der Herr Moderator. Nur leider interessiert es keinen. Was ist denn an dem Code auszusetzen? Den Kurzcode den Sie mir gaben hat funktioniert, jedoch wenn ich den um eine While Schleife erweitern wollte, ließ es sich ohne die Schweifklammern nicht mehr kompilieren. Zu der Frage mit des mehrfachen Einbinden der variables.c: Die Variablen waren zu dem zeitpunkt nicht global gesetzt und das AVR Studio war damit zu frieden, wenn ich die Datei mehrfach einbinden lasse. Ob das Sinn ergibt?! Jetztt sind jedenfalls die Variablen global und es wird nur noch einmal eingebunden, respektive es kommt eh alles in eine Datei.
Karl Heinz schrieb: > while(1){ > Brightness = (adc_byte2 | (adc_byte1 << 8))/4; > > if (Brightness < Limit - 1 && OCR0B < 255) > { > OCR0B++; > } > > else if (Brightness > Limit + 1 && OCR0B > 0) > { > OCR0B--; > } > > _delay_ms(250); > } //end while > } Hierbei wird übrigends nur die Grenze der Hysterese erreicht. bei +-5 würde ich also nur bis auf + oder -5 an das Limit herankommen. Die zweite While-Schleife mit vorgelagerter Abfrage, ob sich mein aktueller Wert außerhalb der Hysterese befinden, arbeitet so lange, bis ich in der Mitte der Hysterese liege. Ich möchte damit vermeiden, dass das Licht wegen jeder Kleinigkeit nachregelt und ggf. schwingt. Grundlegend funktioniert natürlich auch das oben angeführte, aber nicht in dem Funktionsumfang den ich möchte.
Felix schrieb: > Es geht hier eigentlich auch nicht darum in welch feinen und vllt viel > einfachereren Stil ich programmiere, dann würde ich mich nämlich im IT > Sektor aufhalten. Um was geht es denn dann? Was studierst du denn überhaupt? Ist der Kern deiner Arbeit deine ausgefuchste HW-Schaltung oder wie darf man das verstehen? Und der Code dazu ist eher so Nebensache? Hauptsache man hat die Controllerbeinchen korrekt verbunden? Grade bei Embedded ist Software doch mindestens 50% und wenn du weder programmieren kannst noch interesse daran hast das zu ändern warum dann überhaupt ein solches Projekt, und nicht irgendwas ohne Programm? Für sowas sollte man wirklich weder Abschluss noch ak. Grad bekommen, sondern einen satten Tritt.
:
Bearbeitet durch User
@Felix Laß Dich nicht schlecht machen. Es gibt hier ein paar Leute (die immer Gleichen), die an Allem herumkritteln. Reagiere nicht darauf. Dein Programm tut offenbar, was es soll, das zählt und fertig ist die Laube.
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.