Forum: Mikrocontroller und Digitale Elektronik ATTINY84A Rechnung in C


von Felix (Gast)


Angehängte Dateien:

Lesenswert?

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

von Felix (Gast)


Lesenswert?

Zusatz: Es handelt sich bei der berechnung um pwm_calc in der sub-datei 
code.c

von Kai S. (kai1986)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Erwin (Gast)


Lesenswert?

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!

von holger (Gast)


Lesenswert?

>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"

von Julian B. (julinho)


Lesenswert?

diff_brightness = pd_value - brightness_value;

Da würfelst Du verschiedene Datentypen zusammen, ich denke Du mußt da 
Casten.

von Felix (Gast)


Lesenswert?

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

von holger (Gast)


Lesenswert?

>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.

von Felix (Gast)


Lesenswert?

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?

von holger (Gast)


Lesenswert?

>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.

von Felix (Gast)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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
von Felix (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Markus (Gast)


Lesenswert?

Ich denke das zweite while ersezten durch if.

Innerhalb des while (Brightness != 128){}
wird "Brightness" nicht mehr mit den neuen Werten eingelesen.

von Felix (Gast)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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
von Takao K. (takao_k) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Felix (Gast)


Lesenswert?

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.

von Felix (Gast)


Lesenswert?

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.

von Bernd N (Gast)


Lesenswert?

Blindenhund tsss, es ist ein Irrglaube das Blindenhunde blind sind :-)

von Cyblord -. (cyblord)


Lesenswert?

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
von Big Endian (Dickes Ende) (Gast)


Lesenswert?

@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
Noch kein Account? Hier anmelden.