Werte Ingenieure ! Ich bin Hobbyelektroniker und würde gerne folgendes Projekt realisieren. Datenlogger für 10 analoge Eingänge (0-5Volt) Aufzeichnungsfrequenz 100Hz Messdauer 1 - 2 Minuten Messwertauflösung vorerst 1 Byte (eventuell 2Byte) Speicheraufwand: 10Eingänge 2min 100*60 * 1Byte = 120KB -> Speicherkarte Die Realisierung hätte ich mir mit folgenden Komponenten vorgestellt: https://www.exp-tech.de/plattformen/arduino/8137/arduino-mkr-zero-mit-headers 2x https://www.reichelt.at/entwicklerboards-platine-i2c-multiplexer-tca9548a-debo-i2c-multi-p235517.html?PROVID=2788&wt_gata=51942941739_248653657836&PROVID=2788&gclid=Cj0KCQiA_rfvBRCPARIsANlV66PiQ7jthK2SBtqtlh0A5a3pDQQdl4zsCFpwwH_TxFhzNMzbWy4RAs4aAhoHEALw_wcB&&r=1 bevor ich diese Komponenten bestelle bitte ich um eure geschätzte Meinung ob das so eine vernünftige Lösung ist, oder ob es bessere Empfehlungen gibt ?
Du hast vergessen, die AD-Wandler aufzuführen, die du verwenden willst. Ansonsten sollte das wohl schon damit möglich sein.
Ansonsten raspberry a Und als ad Wandler was aus dieser Liste. Z.b die 10 Channel Sigma Delta https://www.analog.com/en/products/analog-to-digital-converters/precision-ad-converters/multiplexed-ad-converters.html
Andreas S. schrieb: > Meinung ob das so eine vernünftige Lösung ist ... das ist für mich keine vernünftige lösung! weil, dein board nur 7 analoge eingänge mitbringt und du 10 als anforderung hast. jetzt darum 2 boards zu nehmen wäre sinnfrei. und für was bitte soll dann noch der multiplexer gebraucht werden? boards mit 12 und mehr analogen eingängen gibt es viele ... z.b. https://www.pjrc.com/store/teensy35.html mt
die einzelnen Messwerte würde ich über I2C einlesen, oder liege ich da falsch ?
Andreas S. schrieb: > die einzelnen Messwerte würde ich über I2C einlesen, oder liege ich da > falsch ? Und wer stellt die analogen Messwerte auf einem digitalen Bus zur Verfügung?
Apollo M. schrieb: > boards mit 12 und mehr analogen eingängen gibt es viele ... z.b. > https://www.pjrc.com/store/teensy35.html ... verstehe ich, aber ich hatte vergessen, dass ich diese Aufgabe mit der Arduino IDE bewerkstelligen möchte, da ich mich da viel leichter tue !
Andreas S. schrieb: > ... verstehe ich, aber ich hatte vergessen, dass ich diese Aufgabe mit > der Arduino IDE bewerkstelligen möchte, da ich mich da viel leichter tue > ! https://www.pjrc.com/teensy/teensyduino.html
... die antworten/fragen zu adc hier kommen garantiert nicht von einem ing., weil nur sinnfrei, sorry eher grob dämlich. also, wenn man keine ahnung hat, besser mal die fresse halten! mt
:
Bearbeitet durch User
Apollo M. schrieb: > ... die antworten/fragen zu adc hier kommen garantiert nicht von einem > ing., weil nur sinnfrei, sorry eher grob dämlich. Fassen wir zusammen: - Der TO möchte 10 Analoge Kanäle (0...5V) loggen - Der TO führt einen Mikrocontroller und einen I2C-Multiplexer auf - Der TO scheint die Analogen Signale mit dem MUX erfassen zu wollen An welcher Stelle genau ist jetzt die Frage nach dem Analog-Digital-Wandler grob dämlich?
Sebastian R. schrieb: > https://www.pjrc.com/teensy/teensyduino.html das würde mir gut gefallen, aber ... oder das Teensyduino Add-on in der Arduino IDE-Entwicklungsumgebung installieren -> kann ich das ?
Sebastian R. schrieb: > - Der TO scheint die Analogen Signale mit dem MUX erfassen zu wollen Ich bitte vielmals um Entschuldigung, das war der falsche Link !!! sorry
Andreas S. schrieb: > kann ich das ? Wenn du in der Lage bist, den Teensyduino-Installer herunter zu laden und du in der Lage bist, das Setup auszuführen und du es bereits geschafft hast, die Arduino IDE zu installieren, dann stehen die Chancen, dass du das kannst, nicht schlecht. Du kannst deine Fähigkeiten in der Hinsicht allerdings besser einschätzen.
Apollo M. schrieb: > ... die antworten/fragen zu adc hier kommen garantiert nicht von einem > ing., weil nur sinnfrei, sorry eher grob dämlich. > also, wenn man keine ahnung hat, besser mal die fresse halten! Du scheinst auch davon betroffen zu sein. Oder kannst du vielleicht deine großen Sprüche mit einer Spur von Argumentation untermauern?
Sebastian R. schrieb: > Wenn du in der Lage bist, den Teensyduino-Installer herunter zu laden > und du in der Lage bist, das Setup auszuführen und du es bereits > geschafft hast, die Arduino IDE zu installieren, dann stehen die > Chancen, dass du das kannst, nicht schlecht. Du kannst deine Fähigkeiten > in der Hinsicht allerdings besser einschätzen. vielen Dank auch an alle anderen, dann werde ich diesen Weg einschlagen !
Andreas S. schrieb: > Sebastian R. schrieb: >> - Der TO scheint die Analogen Signale mit dem MUX erfassen zu wollen > > Ich bitte vielmals um Entschuldigung, das war der falsche Link !!! sorry Dann wäre der richtige Link vielleicht noch spannend. War das zufällig ein Analog-Multiplexer?
Andreas S. schrieb: > Meinung ob das so eine vernünftige Lösung ist, oder ob es bessere > Empfehlungen gibt ? Irgendwie ist nicht ganz klar, was du mit dem I²C-Multiplexer erreichen willst. Warum nicht ein Analogmultiplexer mit 74HC4067 als und dazu einen kleinen Arduino? https://www.ebay.de/itm/311374536627 https://www.ebay.de/itm/201539955347 Welche Auflösung soll dein ADC denn haben? Der ATmega328 bietet 10 Bit.
Wolfgang schrieb: > ... und dazu einen kleinen Arduino? ... und natürlich das SD Karteninterface, z.B. https://www.ebay.de/itm/311823238808
> bessere Empfehlungen gibt ? 8 Kanaele von 0 - 5 V macht ein kleiner PIC 16F684 fuer 50 ct ja schon. Da noch einen EEPROM drangehaekelt und fertig ist die Laube. Mit acht 4051 Muxen laesst sich das ganze auf 64 Kanaele aufblasen.
Ich sehe hier keinen Bedarf für I²C Multiplexer. Du kannst viele I²C Geräte direkt an den Mikrocontroller hängen. Bedenke, dass das von Dir gewählte Arduino Board noch recht jung ist. Es gibt relativ wenig Doku und viele Arduino Bibliotheken funktionieren nur auf 8bit Mikrocontrollern. Hier wirst du womöglich den Quelltext anpassen müssen. Eventuell bist du als Anfänger mit einem klassischen Arduino (also einem mit ATmega Mikrocontroller) besser bedient. Ich würde einen STM32F103 (Bluepill-Board) verwenden. Das hat nämlich 10 analoge Eingänge und die SD Karte kann man direkt ohne Pegelwandler anschließen. Dazu dann den alten STM32Duino Core von Roger Clark (http://stefanfrings.de/stm32/stm32f1.html#arduino), weil der wesentlich schlanker ist, das der Framework-Stapel von ST. Das oben empfohlene Teensy 3.5 Board sieht auch gut aus, das habe ich allerdings noch nie verwendet.
Sebastian R. schrieb: > - Der TO scheint die Analogen Signale mit dem MUX erfassen zu wollen wohl kaum, weil der mux ist ein i2c bus mux! also hier völlig umsonst. > An welcher Stelle genau ist jetzt die Frage nach dem > Analog-Digital-Wandler grob dämlich? fragen zu/um ext. adc sind bei den vom TO genannten anforderungen unsinn, da jeder on chip adc diese erfüllt. mt
Apollo M. schrieb: > wohl kaum, weil der mux ist ein i2c bus mux! also hier völlig umsonst. You Don't say. Deshalb habe ich es angemerkt. Andererseits: Andreas S. schrieb: > Ich bitte vielmals um Entschuldigung, das war der falsche Link !!! sorry
Nochmals vielen Dank an Alle ich versuche es mit dem Teensy ! Und sorry nochmals für das Missverständnis, dass ich leider ausgelöst habe.
Wie wärs mit einem Arduino keine-Ahnung-aber-mit-XMega? Der hat 16 ADCs mit 12 Bit.
Harry schrieb: > Der hat 16 ADCs > mit 12 Bit. Alle, die ich jetzt so spontan gesehen habe, haben auch nur einen ADC, wie die normalen ATMega auch.
Ein ADC aber davor Multiplexer mit 8/16 Eingängen. Bei 100Hz sollte das gehen.
Danke Thomas so war das auch gemeint. Es gibt welche mit 2 echten ADCs und je einem 8-Kanal Multiplexer. Wenn man jeden der ADCs mit einem Eingang verwendet gehen 2 Msps. 100Hz bei 16 Kanälen sollten überhaupt kein Problem sein.
Liebe Helfer, letztlich habe ich mich doch für den MKRZero entschieden, allerdings arbeite ich vorerst mit nur 7 Kanälen. Nachfolgend mein Programm, es funktioniert alles so wie es soll ! Einzig würde mich noch interessieren wieso die serielle Schnittstelle während des Messvorganges getrennt wird ? Und natürlich sind auch konstruktive Verbesserungsvorschläge willkommen :-)
1 | #include <Adafruit_GFX.h> |
2 | #include <Adafruit_SSD1306.h> |
3 | #include <SPI.h> |
4 | #include <SD.h> |
5 | |
6 | #define OLED_RESET 4
|
7 | |
8 | #define DEBUG 0
|
9 | |
10 | #ifdef DEBUG
|
11 | #define DEBUG_PRINT(x) Serial.print (x)
|
12 | #define DEBUG_PRINTDEC(x) Serial.print (x, DEC)
|
13 | #define DEBUG_PRINTLN(x) Serial.println (x)
|
14 | #else
|
15 | #define DEBUG_PRINT(x)
|
16 | #define DEBUG_PRINTDEC(x)
|
17 | #define DEBUG_PRINTLN(x)
|
18 | #endif
|
19 | |
20 | Adafruit_SSD1306 display(OLED_RESET); |
21 | File myFile; |
22 | |
23 | |
24 | |
25 | const char vers[] = "v1.0"; |
26 | const unsigned long period = 5000; // microsec. |
27 | const unsigned long runtime = 60000; // millisec. |
28 | |
29 | unsigned long count = 0; |
30 | |
31 | int sensor = 0; |
32 | int buttonPushCounter = 0; // counter for the number of button presses |
33 | int buttonState = 0; // current state of the button |
34 | int lastButtonState = 0; // previous state of the button |
35 | |
36 | byte i = 0; |
37 | byte runcount = 0; |
38 | |
39 | char fileString[11] = "RUN000.txt"; |
40 | char buf[4] = "000"; |
41 | |
42 | String dataString = "ch1, ch2, ch3, ch4, ch5, ch6, ch7"; |
43 | |
44 | |
45 | |
46 | void setup() { |
47 | |
48 | pinMode(3, OUTPUT); // tone output (not used yet) |
49 | |
50 | pinMode(4, INPUT); // set pin to input |
51 | digitalWrite(4, HIGH); // turn on pullup resistors |
52 | pinMode(5, INPUT); // set pin to input |
53 | digitalWrite(5, HIGH); // turn on pullup resistors |
54 | |
55 | Serial.begin(38400); |
56 | |
57 | // Display
|
58 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Adressierung beachten, hier 0x3C ! |
59 | startup(); |
60 | |
61 | // SD Card
|
62 | // Serial.print("Initializing SD card...");
|
63 | // see if the card is present and can be initialized
|
64 | if (!SD.begin()) { // const int chipSelect = 4 - with this display not neccessary ! |
65 | DEBUG_PRINTLN("card failed, or not present !"); |
66 | SDerror(); |
67 | }
|
68 | |
69 | DEBUG_PRINTLN("card initialized !"); |
70 | myFile = SD.open("runs.txt"); |
71 | // if the file opened okay, write to it
|
72 | if (myFile) { |
73 | DEBUG_PRINT("Reading from SD file..."); |
74 | runcount = myFile.read(); |
75 | DEBUG_PRINT(runcount); |
76 | DEBUG_PRINT(" "); |
77 | runcount += 1; |
78 | myFile.close(); |
79 | SD.remove("runs.txt"); |
80 | }
|
81 | |
82 | myFile = SD.open("runs.txt", FILE_WRITE); |
83 | // if the file opened okay, write to it
|
84 | if (myFile) { |
85 | DEBUG_PRINT("writing to SD file..."); |
86 | myFile.write(runcount); |
87 | DEBUG_PRINT(runcount); |
88 | myFile.close(); |
89 | } else { |
90 | myFile.close(); |
91 | DEBUG_PRINTLN("error opening runs.txt"); |
92 | SDerror(); |
93 | }
|
94 | |
95 | sprintf(buf, "%03d", runcount); |
96 | fileString[3] = buf[0]; |
97 | fileString[4] = buf[1]; |
98 | fileString[5] = buf[2]; |
99 | }
|
100 | |
101 | |
102 | |
103 | void loop() { |
104 | |
105 | // read the pushbutton input pin:
|
106 | buttonState = digitalRead(4); |
107 | |
108 | // compare the buttonState to its previous state
|
109 | if (buttonState != lastButtonState) { |
110 | // if the state has changed, increment the counter
|
111 | if (buttonState == LOW) { |
112 | // if the current state is HIGH then the button went from off to on:
|
113 | buttonPushCounter++; |
114 | DEBUG_PRINTLN("on"); |
115 | DEBUG_PRINT("number of button pushes: "); |
116 | DEBUG_PRINTLN(buttonPushCounter); |
117 | i = countdown(1); |
118 | } else { |
119 | // if the current state is LOW then the button went from on to off:
|
120 | DEBUG_PRINTLN("off"); |
121 | }
|
122 | // Delay a little bit to avoid bouncing
|
123 | delay(50); |
124 | }
|
125 | // save the current state as the last state, for next time through the loop
|
126 | lastButtonState = buttonState; |
127 | |
128 | if (Serial.available()) { |
129 | int inByte = Serial.read(); |
130 | switch (inByte) { |
131 | case 's': |
132 | Serial.println("measuring..."); |
133 | // tone(3, 500, 500);
|
134 | i = start(); |
135 | |
136 | break; |
137 | default:
|
138 | // statements
|
139 | break; |
140 | }
|
141 | }
|
142 | |
143 | if (i == 1) { |
144 | recordData(); |
145 | } else { |
146 | Messwertausgabe(); |
147 | }
|
148 | }
|
149 | |
150 | |
151 | |
152 | void Messwertausgabe(void) { |
153 | display.clearDisplay(); |
154 | display.setTextColor(WHITE); |
155 | display.setTextSize(2); |
156 | display.setCursor(0,0); |
157 | display.print("run: "); |
158 | display.println(runcount); |
159 | display.setTextSize(1); |
160 | display.setCursor(0,18); |
161 | display.print("count: "); |
162 | display.println(count); |
163 | sensor = analogRead(0); |
164 | uint16_t sensorgraph = sensor / 8; // 1.023 -> 127 |
165 | |
166 | display.drawFastHLine(0, 29, sensorgraph, WHITE); |
167 | display.drawFastHLine(0, 30, sensorgraph, WHITE); |
168 | display.drawFastHLine(0, 31, sensorgraph, WHITE); |
169 | display.display(); |
170 | }
|
171 | |
172 | int start(void) { |
173 | display.clearDisplay(); |
174 | display.setCursor(0,0); |
175 | display.println("measuring... "); |
176 | display.display(); |
177 | count = 0; |
178 | return 1; |
179 | }
|
180 | |
181 | void recordData(void) { |
182 | unsigned long timeMillis = millis() + runtime; |
183 | unsigned long timeMicros = 0; |
184 | |
185 | myFile = SD.open(fileString, FILE_WRITE); |
186 | if (myFile) { |
187 | myFile.println(dataString); |
188 | }
|
189 | |
190 | do { |
191 | if (micros() >= timeMicros) { |
192 | timeMicros = micros() + period - 100; // 100us = program runtime |
193 | dataString = ""; |
194 | int analogPin; |
195 | // read seven sensors and append to the string:
|
196 | for (analogPin = 0; analogPin < 6; analogPin++) { |
197 | dataString += String(analogRead(analogPin)) + ","; |
198 | }
|
199 | dataString += String(analogRead(analogPin)); // the last data without komma |
200 | |
201 | if (myFile) { |
202 | myFile.println(dataString); |
203 | } else { |
204 | DEBUG_PRINTLN("error opening filestring"); |
205 | SDerror(); |
206 | }
|
207 | count++; |
208 | |
209 | }
|
210 | } while (millis() < timeMillis); |
211 | |
212 | i = 0; |
213 | myFile.close(); |
214 | }
|
215 | |
216 | void startup(void) { |
217 | display.clearDisplay(); |
218 | display.setTextColor(WHITE); |
219 | display.setTextSize(1); |
220 | display.setCursor(3,1); |
221 | display.println("c A.STOECKL"); |
222 | display.drawCircle(5,5,5, WHITE); |
223 | display.println(); |
224 | display.print("Version: "); |
225 | display.print(vers); |
226 | display.display(); |
227 | delay(3000); |
228 | }
|
229 | |
230 | void SDerror (void) { |
231 | display.clearDisplay(); |
232 | display.setTextColor(WHITE); |
233 | display.setTextSize(1); |
234 | display.setCursor(0,0); |
235 | display.println("SD card or file"); |
236 | display.setTextSize(2); |
237 | display.setCursor(0,10); |
238 | display.print("error"); |
239 | display.display(); |
240 | while(1); |
241 | }
|
242 | |
243 | int countdown (byte j) { |
244 | display.clearDisplay(); |
245 | display.setTextColor(WHITE); |
246 | display.setTextSize(1); |
247 | do { |
248 | for (byte k = 10; k > 0; k--) { |
249 | display.setCursor(0,0); |
250 | display.clearDisplay(); |
251 | display.setTextSize(1); |
252 | display.println("Count down "); |
253 | display.setTextSize(2); |
254 | display.print(k); |
255 | display.display(); |
256 | delay(1000); |
257 | }
|
258 | j = 0; |
259 | } while (j == 1); |
260 | display.setTextSize(1); |
261 | byte i = start(); |
262 | return i; |
263 | }
|
Andreas S. schrieb: > Einzig würde mich noch interessieren wieso die serielle Schnittstelle > während des Messvorganges getrennt wird ? Woran erkennst du, dass sie getrennt wird? Meinst du damit, dass die USB Schnittstelle getrennt wird? Das könnte daran liegen, dass die Bibliothek (insbesondere der SPI Teil) blockierend mit dem Display kommuniziert, so dass die USB Schnittstelle nicht mehr bedient wird. USB wird vom Host (PC) jede Millisekunde gepollt. Wenn der µC nicht schnell antwortet, trennt der PC die Verbindung. Versuche mal, vor "display.display()" einen delay(1) einzufügen. Vielleicht hilft das schon.
Hallo Stefan, ich erkenne es daran, dass ich z.B. während des Messvorganges keine Daten auf den seriellen Port ausgeben kann, bzw. wenn ich nach Abschluss der Messung seriell einen neuen Startbefehl ausgeben möchte muss ich zuerst das Board trennen und wieder verbinden. Ich werden deinen Tipp mit delay versuchen.
Andreas S. schrieb: > Hallo Stefan, > > ich erkenne es daran, dass ich z.B. während des Messvorganges keine > Daten auf den seriellen Port ausgeben kann, bzw. wenn ich nach Abschluss > der Messung seriell einen neuen Startbefehl ausgeben möchte muss ich > zuerst das Board trennen und wieder verbinden. > Ich werden deinen Tipp mit delay versuchen. Auf einem echten seriellen Port (ohne Hardware Handshake) kann man immer Daten ausgeben, egal ob etwas angeschlossen ist, oder nicht. Geht es bei dir um die USB Schnittstelle?
> muss ich zuerst das Board trennen und wieder verbinden.
Das ist bei den uinos doch so ueblich.
Mit Bananen im Kopf kann man nur Affen fuettern.
Stefan ⛄ F. schrieb: > Geht es bei dir um die USB Schnittstelle? ja, es geht um die USB Schnittstelle
Andreas S. schrieb: > ja, es geht um die USB Schnittstelle Das ist die wahrscheinlichste Problemursache, dass die USB Schnittstelle nicht merh schnell genug bedient wird. Vielleicht wegen zu langer Schleifen ohne yield()/delay() oder weil Interrupts zu lange gesperrt werden.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.