Komponentenauswahl, PWM-Projekt

Hallo zusammen!

Kleine Einleitung:
In meiner Bachelorarbeit werde ich einen alten und teuren Mikrocontroller durch einen modernen und günstigeren Ersetzen. Die Aufgabe des Mikrocontrollers ist es von bis zu 10 Sensoren ein PWM-Signal aufzunehmen. Dieses hat die Größenordnung von 1kH.

Da ich schon einige Erfahrung mit dem Arduino gesammelt habe möchte ich einen solchen verwenden.

Ich habe allerdings noch nie ein Projekt durchgeführt, in dem ich ein PWM Signal einlesen muss.

Mein erster Gedanke war es einen Mega oder den Due zu verwenden. Kann mir da wer weiterhelfen?
Für PWM-Signale in der Größenordnung benötige ich Interrupts, richtig?

Nanunan:
Dieses hat die Größenordnung von 1kH.

Bin verwirrt: 1kH?
H steht für Henry, die SI-Einheit der Induktivität

oder meinst du 1kHz?
Hz für Hertz, SI-Einheit für die Frequenz?

Hallo uxomm,

ja meine natürlich Hertz, habe wohl beim Tippen den Buchstaben verschluckt :stuck_out_tongue:

Hallo,

ich sehe mit 10 Interrupts ein zeitliches Problem. Die sperren sich auch gegenseitig. Dann geht was verloren.
Ich würde eine Art Torschaltung machen. Das die Frequenz von 1kHz bekannt und konstant ist macht es leichter.
Dann könnte man den Timer für das Torzeit Fenster darauf abstimmen und während dieses Fensters alle Eingänge permanent im festen Raster abfragen. Quasi von digital zu digital wandeln bzw. abtasten. Dabei nicht die Flanken abfragen sondern nur den High oder Low Pegel. Nur 8 Signale wären besser, passen auf ein Port. Mußte eben noch einen Port für die restlichen 2 Signale verwenden. Deine Abtastfrequenz muß natürlich höher sein. Haste bestimmt schon gelernt.

von bis zu 10 Sensoren ein PWM-Signal aufzunehmen

Die werden vermutlich nicht synchron sein. (Wäre evtl. hilfreich, wenn du nicht so geheim halten würdest, was für Sensoren das sein sollen. Welcher Sensor gibt ein PWM Signal aus?)
Wenn der PWM-Wert auf 1% genau sein soll, brauchst du eine Auflösung von 100 kHz. Das ist schon ziemlich anspruchsvoll und würde auf keinen Fall von Komfort-Funktionen aus der Arduino-Kiste abgedeckt. Ob ein 100 kHz oder schnellerer Timer oder PinChangeInterrupt besser ist, keine Ahnung.

Sicher das es PWM-Signale sind und keine Frequenzen?

Der Unterschied ist:

Ein PWM hat feste Frequenz, variiert das Verhältniss zwischen Berg und Tal.

Eine Frequenz hat meist ein festes Verhältniss, aber wird größer oder kleiner.

Die meisten Sensoren die ich kenne geben Frequenz aus. PWM ist eher ein Ausgang als ein Eingang.

Programmtechnisch ist das ein großer Unterschied. Ist es wirklich PWM, hast du zudem eine feste Frequenz. Musst also Flanken erkennen und mit einem Timestamp versehen, kommt die High-Flanke setzt du den Timestamp auf den aktuellen Wert. Kommt ein Low-Wechsel musst du den Timestamp vergleichen mit aktueller Zeit und daraus die Länge des Impulses ermitteln

10 solche Sensoren ist aber schon recht heftige Last. Weil ein 1% Signal bei 1Khz nur die Impulslänge von 10µsec hat. Man müsste also mindestens alle 10µsec abfragen, 100.000x pro Sekunde über 10 Eingänge pollen. Denke nicht das ein 16Mhz Gerät das kann.

Ist es frequenz zählst du Impulse und fragst regelmässig den Stand ab. Je nach Impulsmenge weist du dann welche Frequenz anliegt. Die Zeit zwischen zwei Abfragen ist abhängig von deiner Min-frequenz und der genauigkeit die du brauchst. 100Hz einmal pro mSec auswerten ist Unsinn. Weil ja nur in jeder 10. Abfrage ein Impuls reinkommt. Kommen also 100-1000hz an, solltest du einmal pro 1/100 sec abfragen. So bekommst du bei 100Hz eine 1 und bei 1000 Hz eine 10. Auflösung ist sehr gering. Alle 1/10 sec abfragen löst dann zwiscchen 10 und 100 auf. 1/10 Sec sollte machbar sein für 10 Sensoren.

Musst also nun erstmal Informationen liefern, damit man weis was man entwickeln muss

Falls es wirklich 10x PWM ist, würde ich bei einem Due mal sowas probieren, das müsste der noch schaffen. Pseudocode:

void loop() {
	// ...
	
	uint32_t aktuell = LeseGanzenPort();
	uint32_t aktuell_zeit = micros();
	
	// nur relevante 10 Bits durchlassen
	aktuell &= Sensormaske;
	
	// welche Bits haben sich geändert
	changed = aktuell ^ vorher;
	
	// Für jeden Sensor so ein if, ist schneller als Schleife
	
	if (changed & MaskeSensor1) {
		if (aktuell & MaskeSensor1) {
		  // Steigende Flanke
		  // aus aktuell_zeit und vorheriger Zeit kann Periodendauer berechnet werden
		}
		else {
		  // Fallende Flanke
		  // aus aktuell_zeit, Zeit der letzten steigenden Flanke und Periodendauer kann PWM-Wert berechnet werden
		}
	}

}

Aber es wäre schon hilfreich zu wissen, was den der alte teure Prozessor für einer ist, ob es davon Code gibt und ganz besonders, was mit den 10 Sensorwerten noch alles passieren soll.

Wie oft musst Du denn messen, wie genau muss es sein und wie oft ändert sich der Wert?
Wenn Du da einen passenden trade-off findest, dann würde ich das überhaupt nicht digital machen, sondern analog, ein einfacher RC-low-pass filter kann Dir z.B. das Signal in eine echte Spannung umsetzen, die Du dann analog messen kannst.
Folgender Schaltkreis mit 1kOhm und 100uF ist z.B. bei 50% duty-cycle auf ca. 0.5% des Maximalwertes genau (ließe sich natürlich durch Mitteln steigern, aber auch wieder auf Kosten der Geschwindigkeit), braucht aber ungefähr 120ms, um sich mit 1% Genauigkeit von 0% auf 100% umzustellen. (Beides durch Ansehen des virtuellen Oszis geschätzt, solltest Du natürlich genauer berechnen).
Reduzierst Du Widerstand oder Kapazität, geht es schneller, aber mit mehr (also ungenauer), erhöhst Du sie, geht es genauer, dauert aber länger.

Zum Messen kannst Du dann z.B. sowas nehmen ADS1115 16-Bit ADC - 4 Channel with Programmable Gain Amplifier : ID 1085 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits. 16bit machen natürlich nur Sinn, wenn Du entweder hohe C/R-Werte hast, oder stark mittelst.

Die analoge Variante kam mir auch zuerst in den Sinn. Wenn 12 Bit Auflösung reichen, kommt auch wieder der Due oder der Teensy in Frage, beide haben genügend analoge Eingänge.

Hallo zusammen, danke für die vielen Antworten.

Doc_Arduino:
ich sehe mit 10 Interrupts ein zeitliches Problem. Die sperren sich auch gegenseitig. Dann geht was verloren.

Guter Einwand, denke die Interrupts kann ich vergessen.

michael_x:
Die werden vermutlich nicht synchron sein. (Wäre evtl. hilfreich, wenn du nicht so geheim halten würdest, was für Sensoren das sein sollen. Welcher Sensor gibt ein PWM Signal aus?)

Genau, die Sensoren werden nicht parallel sein. Zum Signal kann ich leider keine genauen Angaben machen, ist alles Firmengeheimnis. Das bremst mich hier leider etwas aus :frowning:

Es erfolgt zu Anfang eine Initialisierung, in der ein PWM Signal abgegeben wird. Dann gibt der Sensor ca. alle 3 Sekunden seine 3 Parameter von sich. Diese 3 Parameter definieren sich jeweils über die "HIGH" Länge des Signals. Ich stimme @chefin zu, ist nicht ganz richtig hier von PWM zu reden. Gebe die Beschwerde an den Abteilungsleiter weiter :stuck_out_tongue:

Also nochmal zum Signal, Parameter 1 hat ein 700ms Fenster. Je nachdem wie lange das Signal hiervon High ist, bestimmt sich der Wert.

Triviales Beispiel, 350ms von 700ms = 25m Abstand.

Gleiches gilt dann für Parameter 2 und 3...

ArduFE:
Falls es wirklich 10x PWM ist, würde ich bei einem Due mal sowas probieren, das müsste der noch schaffen. Pseudocode:

Werde den Due mal anschaffen.
Idee von mir, falls die Rechenleistung nicht ausreicht, jeweils 2 Due für 5 Signale, dann einen weiteren, der die ankommenden Signale nur aufnimmt und an den PC sendet?

ElCaron:
Wie oft musst Du denn messen, wie genau muss es sein und wie oft ändert sich der Wert?

Nun, jede 3 Sekunden sollten reichen, meistens werden die Messungen über 24h durchgeführt und dann ausgewertet. Langzeitbelastungstests also. Deine Idee gefällt mir sehr gut, ob die 3300 Samples pro Sekunde ausreichen bezweifle ich aber...

Nanunan:
Werde den Due mal anschaffen.
Idee von mir, falls die Rechenleistung nicht ausreicht, jeweils 2 Due für 5 Signale, dann einen weiteren, der die ankommenden Signale nur aufnimmt und an den PC sendet?

Wenn ein einzelner Due nicht reicht, würde ich mich eher in Richtung Teensy orientieren. Das ist zumindest ein Verwandter der Arduinos. Paul Stoffregen, sein Konstruktuer, ist im englischen Teil des Forums sehr aktiv und liefert auch Code-Beiträge zur Arduino IDE. Ein Teensy ist viel kleiner als ein Due, nur etwas größer als ein Arduino Pro mini. Auf der Fläche eines Due könnte man 5-6 Teensy anordnen.
http://pjrc.com/teensy/index.html

Den Teensy 3.2 kann man mit 96 MHz übertakten (Standard ist 72), das ist eventuell noch etwas schneller als der Due, auch wenn es ein kleiner Controllertyp ist. Und wie man hier im Forum liest, kommt demnächst der Teensy 3.5, mit 180 MHz, übertaktbar auf über 200.

Und wenn es auch ohne Arduino IDE geht, gäbe es da noch sowas
https://developer.mbed.org/platforms/ST-Nucleo-F446RE/
https://developer.mbed.org/platforms/ST-Nucleo-F746ZG/

@ArduFE:
Vom Teensy habe ich bis jetzt noch nichts gehört, werde mir den mal angucken.

Weitere Idee von mir, das gesamte Projekt über Matlab/Simulink umsetzen?

Haben im Studium einen Arduino Mega als PID-Regler verwendet, habe damit gute Erfahrungen gemacht...

Nanunan:
Nun, jede 3 Sekunden sollten reichen, meistens werden die Messungen über 24h durchgeführt und dann ausgewertet. Langzeitbelastungstests also. Deine Idee gefällt mir sehr gut, ob die 3300 Samples pro Sekunde ausreichen bezweifle ich aber...

Wo hast Du bei meiner Idee die 3300 Samples/s her? Wenn Dir ein Messwert alle 3 Sekunden reicht und dabei nicht wichtig ist, dass Du einen wert zwischen dem aktuellen und dem von vor 120ms erhälst, brauchst Du nciht 3300/s, sondern einen alle 3 Sekunden.