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
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"
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
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.
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.
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?
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
elseif(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.
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.
@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.