Forum: Mikrocontroller und Digitale Elektronik 8x S0 Schnitstellen Logger mit AVR


von Dennis H. (somebuddy)


Lesenswert?

Guten Tag,

Meine Aufgabenstellung besteht darin 8 S0 Signale zu loggen und 
entsprechend zu visualisieren. [ Drehstromzähler ]

Einem Atmega1284P zusätzlich zu dem "Webserver" noch das loggen von 8 
Impulsen zuzumuten ,ist warscheinlich zuviel des Guten.

Daher dachte ich für die 8 S0 Signale an einen extra AVR.

Wie würdet ihr das loggen realisieren ?

Atmega 8 und die 8 Pins pollen und Variablen inkrementieren ?

Atiny mit 9 externen Interrupts  und in den Int Routinen inkrementieren 
?
Was passiert wenn zwei interrupts gleichzeitig ausgelöst werden ?

Schonmal vielen Dank für eure Anregungen !

Grüße
Dennis

von spontan (Gast)


Lesenswert?

Pollen, incrementieren.
Warum nicht in einem Baustein?
Die Kommunikation zwischen 2 µC gibts auch nicht ohne Zeitaufwand.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Meine Aufgabenstellung besteht darin 8 S0 Signale zu loggen und
> entsprechend zu visualisieren. [ Drehstromzähler ]

Für mich ist S0 eine ISDN-Schnittstelle.

Für dich vermutlich nicht :), insofern solltest du erstmal beschreiben,
worum es bei der Aufgabe überhaupt geht.

Dennis Henning schrieb:
> Was passiert wenn zwei interrupts gleichzeitig ausgelöst werden ?

Wenn sie wirklich gleichzeitig anliegen (auf den CPU-Takt genau),
dann "gewinnt" der, der eine höhere Priorität hat (beim AVR: dessen
Vektor in der Tabelle die niedrigere Adresse hat).  Dessen ISR wird
zuerst abgearbeitet, und sofern sie nicht zwischendrin die Interrupts
wieder freigibt, wartet der zweite zeitgleich anliegende Interrupt
dann bis zum RETI.

Wenn während einer Interruptsperre (also bspw. während der
Abarbeitung einer ISR) ein weiterer Interrupt mehr als einmal
auftritt, dann geht in der Regel ein Ereignis verloren (Ausnahme:
UART-Empfang ist teilweise doppelt gepuffert).

Inwiefern Interrupts aber überhaupt sinnvoll/geeignet dafür sind,
hängt von der Art deiner Signale ab.  Siehe oben, die müsstest du
einem Dummen nochmal irgendwie beschreiben.

von Dennis H. (somebuddy)


Lesenswert?

Vielen Dank schonmal.. !

S0 Schnitstelle :

http://www.mikrocontroller.net/articles/S0-Schnittstelle#Interne_Beschaltung


Einer der 8 Drehstromzähler liefert z.B. Pro "verbrauchte" kWh 1000 
Impulse.
( Open Collector )

In einem Bausteil lässt sich das zusammen mit einem IP Stack ( Webserver 
) wohl nicht lösen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:

> S0 Schnitstelle :
>
> http://www.mikrocontroller.net/articles/S0-Schnittstelle#Interne_Beschaltung

Schön, existierende Begriffe völlig artfremd wiederzuverwenden ...

Zumindest sollte nichts prellen, damit sind Interrupts benutzbar.

> Einer der 8 Drehstromzähler liefert z.B. Pro "verbrauchte" kWh 1000
> Impulse.

Maximale Leistung?  Bei 10 kW wären das 10000 Impulse/h oder etwa 3 Hz.
Darüber lächelt ein AVR müde, selbst wenn man ihn nur mit 1 MHz
taktet.

> In einem Bausteil lässt sich das zusammen mit einem IP Stack ( Webserver
> ) wohl nicht lösen.

Warum denn nicht?

von Dennis H. (somebuddy)


Lesenswert?

Gehen wir mal von dem Fall 8 x 10 kW aus.
Wären also 8x 10000 Impulse.

Ich war der Meinung ,das ein Pollen von 8 Eingängen meinen Webserver 
wohl mehr als stören würde.
Beides zusammen auf einem Atmega1284p.
Oder bin ich auf dem Holzweg ?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Ich war der Meinung ,das ein Pollen von 8 Eingängen meinen Webserver
> wohl mehr als stören würde.

Das Problem beim Pollen ist, dass du garantiert während eines Impulses
mindestens einmal gepollt haben musst.  Die genaue Impulslänge finde
ich auf die Schnelle nicht, Wikipedia spricht von 70 ms.  Damit musst
du aller 50 ms pollen, was zwar nicht viel ist, aber schon ein wenig
Grundlast erzeugt (zumal du ja dann noch die Flankendetektierung
machen musst, damit du jede Impulsflanke nur einmal zählst).

Aber maximal 240 Interrupts pro Sekunde (für angenommene gleichzeitige
10 kW je Zähler) sind Spaß für einen Controller.

Du musst nur dran denken, dass die 32-bit-Variablen, die du in der
ISR hochzählst, außerhalb der ISR beim Auslesen eine Interruptsperre
brauchen, damit der Lesevorgang atomar ist.

von Joerg F. (felge1966)


Lesenswert?

Für die Grundlagen kannst du dir ja schon mal die Elektor (10/2012) 
durchlesen:
http://www.elektor.de/jahrgang/2012/oktober/stromzahler-im-netz.2268818.lynkx

von Dennis H. (somebuddy)


Lesenswert?

Ich finde den Zusammenhang zu den "240 Interrupts" gerade nicht.
Polling hat doch nun nichts mit Interrupts zu tun !?

Oder reden wir von einem µProz welcher 8 externe Interrupts bietet ?

von Frank (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Zumindest sollte nichts prellen, damit sind Interrupts benutzbar.

Da wäre ich mir nicht so sicher.

Einfache (Ferraris-)Zähler haben oft einen Magneten und ein Reed-Kontakt 
eingebaut oder einen mechanischen Kontakt ...

-Frank-

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Oder reden wir von einem µProz welcher 8 externe Interrupts bietet ?

Ja, davon ging ich aus.  ATmega1281 zum Bleistift.

Frank schrieb:
> Einfache (Ferraris-)Zähler haben oft einen Magneten und ein Reed-Kontakt
> eingebaut oder einen mechanischen Kontakt ...

OK, das muss Dennis nun selbst wissen.  Wenn man mit Kontaktprellen
rechnen muss, dann sollte man pollen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

p.s.: Habe gerade mal nachgerechnet, eine ISR, die eine 32-bit-
Variable hochzählt, braucht 55 Takte, zuzüglich 6 Takte für die
Interruptannahme sind es 61.  Wenn du einen Webserver da drauf
setzen willst, wirst du sicher nicht mit 1 MHz arbeiten wollen
sondern eher mit 16, das sind dann knapp 4 µs.  Deine angenommenen
240 Interrupts pro Sekunde benötigen dann also eine Bearbeitungszeit
von weniger als 1 ms, oder 0,1 % des Gesamtbudgets.

von Dennis H. (somebuddy)


Lesenswert?

Danke für das vorrechnen ! :)

Ich rede von elektronischen Zählen ( Prellen ausgeschlossen ) ( Open 
Collector )

Geplant war der Atmega1284P @ 20Mhz

Sollte mit den 8 Externen Interrupts ja zurecht kommen.

Vielen Dank schonmal!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Geplant war der Atmega1284P @ 20Mhz

Gibt's einen Grund für genau den?

> Sollte mit den 8 Externen Interrupts ja zurecht kommen.

Nö, er hat nur drei "echte" Externinterrupts.

Pin-change interrupts kann man dafür auch nehmen, aber das wird
komplizierter:

. einen Interrupt für fallende und steigende Flanke (pin change
  eben)

. nur einen Interrupt für bis zu acht Leitungen, man muss also
  in der ISR wieder die Zustandsänderung jedes einzelnen Pins
  erfassen

Alles in allem kann man dann wohl auch gleich bpsw. aller 10 ms
pollen.  Ist auch nicht so viel schlimmer, 8 Externinterrupts wären
halt nur schneller als Code hingeschludert. ;-)

von Dennis H. (somebuddy)


Lesenswert?

Den Atmega1284P weil mein "Projekt" ( Layout ) auf dem Web Module von 
Ulrich Radig aufbaut.

http://www.ulrichradig.de/home/index.php/avr/avr-webmodule

Und der 1284P zu dem von ihm verwendeten Atmega644 Pin kompatibel ist.

Seitens Webserver sollte sich der Code ja nicht wesentlich unterscheiden 
, wenn ich statt dem Atmega644 / 1284P  nun ein Atmega1281 einplane. 
Oder ?

Was genau meinst du nun mit "echten" Interrupts ? Woran erkenne ich 
diese im Datenblatt ?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Seitens Webserver sollte sich der Code ja nicht wesentlich unterscheiden
> , wenn ich statt dem Atmega644 / 1284P  nun ein Atmega1281 einplane.

Idealerweise solltest du den C-Quellcode 1:1 weiterbenutzen
können.

> Was genau meinst du nun mit "echten" Interrupts ? Woran erkenne ich
> diese im Datenblatt ?

Sieh dir das Kapitel über die Externinterrupts mal an, da gibt es
zwei verschiedene: INTx und PCINTx.  Der ATmega1284P hat bei INTx
nur INT0 bis INT2, der ATmega1281 dagegen hat INT0 bis INT7.
Letztere sind auf zwei Ports verteilt (PE0 ... PE3, PE4 ... PE7),
aber das wird dich wohl nicht stören.

Die "echten" Interrupts kann man pro Pin konfigurieren (fallende
oder steigende Flanke und dergleichen), und sie haben jeder einen
eigenen Vektor.  Bei den Pin-Change-Interrupts werden die 8 Pins
eines Ports zu einem gemeinsamen Vektor zusammengefasst, sodass man
in der ISR erst einmal ermitteln muss, was denn genau die Ursache
war.  Außerdem reagieren sie (für alle freigeschalteten Pins eines
Ports) grundsätzlich sowohl auf die steigende als auch die fallende
Flanke.

von Dennis H. (somebuddy)


Lesenswert?

Gut..  !

Vielen Dank für diese ausführlichen Erklärungen !
Werde mir das Kapitel zu Gemüte führen und mich dann mal an ein neues 
Layout setzen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Werde mir das Kapitel zu Gemüte führen und mich dann mal an ein neues
> Layout setzen.

Wie geschrieben, natürlich geht das auch alles mit 10 ms Polling,
wenn du schon ein fertiges Layout hast.  Ist halt nur in der
Software etwas aufwändiger zu schreiben, aber der gesamte
Rechenzeitbedarf spielt gewiss trotzdem keine Geige.

Wichtig für die Konfiguration des Polling wäre allerdings, die
Mindestimpulsbreite zu kennen.  Bei einem Externinterrupt spielt
das keine Rolle, solange er mindestens zwei CPU-Takte breit war.

von Dennis H. (somebuddy)


Lesenswert?

Ein neues Layout schadet dem "Lerneffekt" nicht wirklich ;)

Gibt es dennoch zufällig ein 44Pin Modell , welches genügend "echte" 
Interrupts bietet ?
Stoße da mit meinen gewünschten Funktionen an ein Platzproblem ( 
Hutschienen Gehäuse )

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dennis Henning schrieb:
> Gibt es dennoch zufällig ein 44Pin Modell , welches genügend "echte"
> Interrupts bietet ?

Bei den Standard-AVRs meines Wissens nicht.

> Stoße da mit meinen gewünschten Funktionen an ein Platzproblem (
> Hutschienen Gehäuse )

Entweder auf QFN als Gehäuse gehen (dann sind die '1281 schon recht
klein) oder auf Xmega.  Dort werden die Externinterrupts über das
Eventsystem vermittelt, du brauchst also einen mit (mindestens) 8
Event-Kanälen, wenn du 8 unabhängige Externinterrupts aufsetzen
willst.  Der ATxmega*D4 müsste das in einem 44poligen Gehäuse
schaffen, wenn ich das Datenblatt richtig verstehe.

von Dennis H. (somebuddy)


Lesenswert?

Würdest du von der Alternative einen zweiten µ ( ATiny ) mit 
entsprechenden Interrupts einzusetzen abraten ?

Dieser könnte lediglich die Interrupts handhaben und die Werte 
zwischenspeichern.

Dieser könnte auf der Trägerplatine Platz finden und die Aufsteck 
Platine in Form des "Webservers" wäre somit "Modular" auch für andere 
Applikationen denkbar.

Oder wird eine Kommunikation zwischen zwei µ's dann zu Zeitkritisch ?
In Zusammenhang mit den Interrupts ( ATiny auf Träger ) und Webserver ( 
AtMega auf Aufsteckplatine )

Vielen Dank für die Unterstützung !

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich hab sowas mal für jemanden gebaut. ATMega32, 28 S0-Eingänge, 
serielle Schnittstelle, als Zählerspeicher I2C-FRAM. Polling 
10ms-Raster, völlig unkritisch das Ganze.

von Dennis H. (somebuddy)


Lesenswert?

Ich finde auch keinen ATiny mit 8 Ext- Interrupts. Weiß nicht wo ich das 
aufgeschnappt habe. Wohl "verlesen.."

von Dennis H. (somebuddy)


Lesenswert?

@ H.Joachim

Du hältst also einen Webserver auf einem ATMega1284P  mit Polling auf 
8-10 Ports für S0  parallel für machbar ?

Könntest du deine Polling Routine zur Verfügung stellen ?

Grüße

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich weiss ja nicht, inweiweit der Webserver den AVR auslastet. Aber alle 
10ms nen Timerinterrupt, darin 8 Eingänge abzufragen, zu entprellen und 
8 long-Variablen zu incrementieren, sollte immer drin sein.
Ich suchs mal raus, ist schon 3 oder 4 Jahre her.
Hast du denn schon die Eingangsbeschaltung in Hardware gegossen? Der 
S0-Ausgang ist etwas eigenartig. Die sinnvollste Eingangsschaltung: 
Optokoppler.

von lol (Gast)


Lesenswert?

Wenn Polling funktioniert, dann geht es mit dem PinChange-Interrupt erst 
recht!

Warum denn immer so kompliziert? (Und warum immer 10 Avrs, wenn einer 
reicht?)

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich bin in dem Fall kein Freund des Interrupts. Prinzipbedingt werden 
wohl längere Leitungen angeschlossen werden müssen, es ist mit Störungen 
zu rechnen. Also wird man auch auf den pinchange-int eine zeitgesteuerte 
Routine aufsetzen müssen, um nachzuschauen, ob das wirklich ein Impuls 
oder ein spike war.
Oder ne Hardware-Entprellung, dann kann man die Vorteile des pinchange 
voll nutzen :-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

lol schrieb:
> Wenn Polling funktioniert, dann geht es mit dem PinChange-Interrupt erst
> recht!

Bringt aber keine Vorteile.  Der Code wird dadurch nicht mehr
einfacher.

von Jens M. (Gast)


Lesenswert?

H.joachim Seifert schrieb:
> Prinzipbedingt werden wohl längere Leitungen angeschlossen werden müssen,
> es ist mit Störungen  zu rechnen.

Da die SO Schnittstelle laut Wikipedia bis zu 30mA liefern kann ist es 
doch kein Problem die Verbindung durch verdrillte Leitungen und 
niederohmigen Abschluss so auszulegen das da nichts mehr stört.

In der selben Quelle steht das die minimale Pulsweite 70ms (= 70.000 µs) 
beträgt.

Da kann man die Pin Change Interrupts ja als eine Art Sammelregister 
interpretieren und die Zeit zwischen den Flankenwechseln stoppen. (zwei 
Timerwerte + Überlauf voneinander abziehen). Womit durch min./max. 
Filterung gleichzeitig die Plausibilität geprüft werden kann.

Das braucht selbst im worst case (8 gleichzeitig abzuarbeitende 
Interruptflags) nur wenige µS. Womit die Messung in Sachen Auflösung und 
Geschwindigkeit um Größenordnungen besser ist als die Pulse je ankommen 
können.

Ich arbeite mit anderen Controllern, aber das lässt sich wohl mit fast 
jedem realisieren der mit mehr als einem Uhrenquarz (32 kHz) getaktet 
wird.

von Dennis H. (somebuddy)


Lesenswert?

Jens Martin schrieb:
> Da kann man die Pin Change Interrupts ja als eine Art Sammelregister
> interpretieren und die Zeit zwischen den Flankenwechseln stoppen. (zwei
> Timerwerte + Überlauf voneinander abziehen). Womit durch min./max.
> Filterung gleichzeitig die Plausibilität geprüft werden kann.

Wie kann ich mir das vorstellen ? Koenntest du evtl. den Ablauf "kurz" 
beschreiben ?

Die Hardware Schnittstelle war folgendermaßen geplant :

http://www.mikrocontroller.net/wikifiles/e/eb/SOext.png

von H.Joachim S. (crazyhorse)


Lesenswert?

Jens Martin schrieb:
> interpretieren und die Zeit zwischen den Flankenwechseln stoppen. (zwei
> Timerwerte + Überlauf voneinander abziehen). Womit durch min./max.
> Filterung gleichzeitig die Plausibilität geprüft werden kann.

Merkst du was? :-)

von Dennis H. (somebuddy)


Lesenswert?

Dass ihr quasi vom "selben" sprecht habe ich gemerkt :) nur noch nicht 
wirklich verstanden wie ich es mir in "Pseudocode" vorzustellen habe.

von Frank (Gast)


Lesenswert?

Ein Arduino Uno mit Ethernetshield (beides für zusammen ca. 40 Euro) in 
einem Hutschienen-Leergehäuse dürfte perfekt für diesen Zweck geeignet 
sein ...

von Jens M. (Gast)


Lesenswert?

H.joachim Seifert schrieb:
> Merkst du was? :-)

Ja, das man nicht zur nachtschlafenden Zeit posten sollte ;-).


Frank schrieb:
> Ein ..... mit .... (beides für zusammen ca. 40 Euro) in
> einem Hutschienen-Leergehäuse dürfte perfekt für diesen Zweck geeignet
> sein ...


Weil er ja störfest ist, Schaltschrankspannung kann, 
Schraub-Klemmanschlüsse hat die Eingänge 24v kompatibel sind und auch 
sonst alles mitbringt was in der Welt der Steuerungs- und 
Automatisierungstechnik so gefordert ist.


Etwas off topic und nur als Beispiel gedacht:
dahingegen hat z.B. eine Siemens Logo (Zykluszeit ca. 10ms - was 
ausreichend ist) das alles von Haus aus, sämtliche Zulassungen und ist 
auch noch dafür Vorgesehen. Hat ne CF Card zum beschreiben und nen 
Ethernet Anschluss zum programmieren.


Nachteil: 3x so teuer ~120 € und ich weiß nicht ob man über Ethernet an 
die Daten kommt.

von Frank (Gast)


Lesenswert?


von lol (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Bringt aber keine Vorteile.

- freier Timer
- kaum CPU-Auslastung

> Der Code wird dadurch nicht mehr
> einfacher.

- 3-Zeiler um PinChange zu initialisieren
- Flankenerkennung ist ebenfalls simpel:
1
uint8_t temp = PINx;
2
uint8_t steigende_flanke = (temp ^ old_pinx) & temp;
3
old_pinx = temp;

Da ist Polling wahrscheinlich doch aufwändiger.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

lol schrieb:
> Jörg Wunsch schrieb:
>> Bringt aber keine Vorteile.
>
> - freier Timer

Atmel gibt dir für die nicht benutzten Timer kein Geld zurück.

Außerdem würde das Pollen im "heartbeat" mitlaufen, den man sowieso in
praktisch jeder Applikation irgendwie braucht.

> - kaum CPU-Auslastung

Das Pollen geht genauso im Rauschen unter.

>> Der Code wird dadurch nicht mehr
>> einfacher.

> - 3-Zeiler um PinChange zu initialisieren
> - Flankenerkennung ist ebenfalls simpel:
1
uint8_t temp = PINx;
2
uint8_t steigende_flanke = (temp ^ old_pinx) & temp;
3
old_pinx = temp;

Dann hast du aber keine Spike-Unterdrückung bzw. Plausibilitäts-
erkennung bezüglich der Impulslänge mehr, die du ja eigentlich noch
haben wolltest.

> Da ist Polling wahrscheinlich doch aufwändiger.

Die Flankenerkennung bleibt die gleiche.

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.