Forum: Mikrocontroller und Digitale Elektronik Attiny26 Zeitstempel im Programm - (Leistungsmessung)


von HeadyCS (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

kurz zum Hintergrund:

Ich möchte mit einem µC eine Drehstrom-Leistungsmessung realisieren. An 
den Analogeingängen kommen die jeweligen aufbereiteten positiven 
Sinus-Halbwellen Signale der 3 Spannungs und 3 Stromwandler an.
Am PWM Ausgang soll die Drehstrom-Wirkleistung ausgegeben werden.

Eine Testschaltung mit einer Phase und einem Arduino Uno hat 
funktioniert.

Das Arduino Programm ist im Anhang.
Kurze Programm Erläuterung:
Aus den Analogeingängen werden Spannung und Strom kontinuierlich 
eingelesen und der höchste Wert mit Zeitstempel gespeichert (û und î).
Nach dem Spannungsnulldurchgang wird die Periodendauer der vorherigen 
Periode und die Phasenverschiebung durch die Zeitstempel ermittelt. 
Desweiteren wird dann die Leistung mit
P = U * I cos phi = û/wurzel(2) * î/wurzel(2) * cos phi
ermittelt.


Jetzt soll das ganze auf einer externen Platine mit einem µC aufgebaut 
werden. Da habe ich den Attiny26 ausgesucht, er hat die IO's die ich 
benötige und war bei Conrad verfügbar.

Jetzt muss ich das Programm aus Arduino in C in Atmel Studio umwandeln, 
dass es auf den Attiny26 übertragen werden kann. In C für µC bin ich 
noch Anfänger, eine einfache Blinkschaltung geht so.

Einen Code zum Auslesen der Analogeingänge habe ich gefunden: 
http://rn-wissen.de/wiki/index.php?title=ADC_%28Avr%29
ebenso zur Ausgabe der PWM: 
http://rn-wissen.de/wiki/index.php?title=Timer/Counter_%28Avr%29

Jetzt bin ich auf der Suche nach einem Code für eine Zeiterfassung, da 
habe ich noch nichts gefunden.

In Arduino kann man mit t1 = millis(); die interne Zeit in µS erfassen. 
An einer anderen Programmstelle ebenso und dann mit t2 - t1 die delta 
Zeit berechnen.
Das bräuchte ich hier in C.

von Couka R. (Gast)


Lesenswert?

Dafür gibt's Timer. Wenn dein Attiny schon LEDs blinken lässt und PWM 
produziert, wirst davon doch sicher schon gehört haben, oder?

lg, couka

von HeadyCS (Gast)


Lesenswert?

Ich dachte es gäbe schon eine Funktion die man nur einzubinden bräuchte.

Auf Basis von hier: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR#Overflow_Interrupt
habe ich es ins Blinkprogramm eingebunden:

1
#define F_CPU 1000000UL
2
3
#include <avr/io.h>
4
//#include <util/delay.h>
5
#include <avr/interrupt.h>
6
7
8
unsigned long time_us(void);
9
10
unsigned long isr_timer0_count1 = 0;
11
void timer_init(void)
12
{
13
  // Timer 0 konfigurieren
14
  TCCR0 = (1<<CS00); // Prescaler 0  
15
  // Overflow Interrupt erlauben
16
  TIMSK |= (1<<TOIE0);  
17
  // Global Interrupts aktivieren
18
  sei();
19
}
20
21
void setup(void)
22
{
23
  timer_init();
24
  DDRA = (1<< PA0);
25
}
26
27
int main(void)
28
{
29
  setup();
30
  
31
  unsigned long zeit = 0;
32
  
33
  char led_ein = 0;
34
35
  while (1)
36
  {
37
38
    unsigned long t1 = time_us();
39
    
40
    if (t1 > zeit+200000)
41
    {
42
      zeit = t1;
43
      if (led_ein)
44
      {
45
        PORTA = 0;
46
        led_ein = 0;
47
      }
48
      else
49
      {
50
        PORTA |= (1 << 0);
51
        led_ein = 1;
52
      }
53
    }
54
    
55
  }
56
}
57
58
/*
59
Der Overflow Interrupt Handler
60
wird aufgerufen, wenn TCNT0 von
61
255 auf 0 wechselt (256 Schritte)
62
*/ 
63
ISR (TIMER0_OVF0_vect)
64
{
65
  // Interrupt Aktion
66
  isr_timer0_count1++;
67
}
68
69
unsigned long time_us(void)
70
{
71
  unsigned long time = ((isr_timer0_count1*256 + TCNT0) / F_CPU) * 1000000;  
72
  return time;
73
}


Problem: Die LED leuchtet etwa 1.2s statt 200ms lang. Kann man da noch 
was optimieren?
Der Attiny26 läuft noch mit 1 MHz internen Takt.

von Michael U. (amiga)


Lesenswert?

Hallo,

wenn Du den Tiny261 statt des Tiny26 nimmst gibt es bereits eine 
Erweiterung für die Arduino-IDE.
Mal
http://drazzy.com/package_drazzy.com_index.json
in den Vorinstellungen als Boardmanager-URL hinzufügen und mit dem 
boardmanager installieren.

Für den Tiny26 hat wohl keiner mehr eine boards.txt gebaut.

Nur, falls Du bei der Arduino-ID bleiben willst und Dein Programm so 
schon macht, was es soll.
Es gibt auch Einbindungen für die Arduino-Bibliotheken ins Atmel-Sturdo, 
habe ich aber nie benutzt.

Ansonsten eben alles "zu Fuß" neu machen, ist vom Lernerfolg sicher 
qauch kein Fehler.

Gruß aus Berlin
Michael

von Klaus (Gast)


Lesenswert?

HeadyCS schrieb:
> Aus den Analogeingängen werden Spannung und Strom kontinuierlich
> eingelesen und der höchste Wert mit Zeitstempel gespeichert (û und î).
> Nach dem Spannungsnulldurchgang wird die Periodendauer der vorherigen
> Periode und die Phasenverschiebung durch die Zeitstempel ermittelt.
> Desweiteren wird dann die Leistung mit
> P = U * I cos phi = û/wurzel(2) * î/wurzel(2) * cos phi
> ermittelt.

Das verstehe ich nicht wirklich. Wenn ich Strom und Spannung aller 
Phasen in einer zeitlichen Auflösung messe, daß man ein Maximum erkennen 
kann, kann ich doch die Leistung einfach direkt errechnen. Aus Strom, 
Spannung und Abtastrate bekomme ich direkt die Wirkleistung, dann über 
alle Phasen aufsummiert und passend gemittelt. Die Rechnung oben passt 
doch nur für einen reinen Sinus und ist eigentlich eine Hilfslösung für 
Drehspulinstrumente.

MfG Klaus

von Mikrocon T. (-42-)


Lesenswert?

Klaus schrieb:
> Aus Strom,
> Spannung und Abtastrate bekomme ich direkt die Wirkleistung,

Die Wirkleistung? Oder die Arbeit?

Für Leistung reicht wohl Strom und Spannung.
;-)

MfG

von HeadyCS (Gast)


Angehängte Dateien:

Lesenswert?

Zwischenstand:
Der Attiny26 läuft mittlerweile mit einen 16 MHz Quarz.

Den Prescaler vom Timer1 habe ich auf 256 gesetzt, sowie die Funktion 
time_us angepasst:
1
unsigned long time_us(void)
2
{
3
  unsigned long time = isr_timer0_count1*4096 + TCNT0 *16;  
4
  return time;
5
}

Die Blinkzeit wurde von 200ms auf 1s erhöht. Oszi sagt on-time: 1,000s 
bzw. frequenz: 500mHz - für mich ist das genau genug.


Den ADC Code habe ich implementiert. Beim PWM Code bin ich gerade dabei.

Zum Flashen ist der Attiny26 mit den MISO  MOSI  SCK / RESET Pins mit 
dem Arduino Board verbunden.

Als PWM Pin möchte ich den PB3 (OC1B) verwenden. Wenn man diesen Pin als 
Ausgang im Programm setzt, sperre ich mich dann aus (kein flashen mehr 
möglich), da PB2 SCK und OC1B invert ist? Weil AVRdude meckert dass die 
Fuse geändert werden.

von spess53 (Gast)


Lesenswert?

Hi

> Wenn man diesen Pin als
>Ausgang im Programm setzt, sperre ich mich dann aus (kein flashen mehr
>möglich), da PB2 SCK und OC1B invert ist?

Warum? Welchen Zustand haben deine PINs bei RESET=L?

MfG Spess

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.