Forum: Mikrocontroller und Digitale Elektronik Datenlogger 10Kanal


von Andreas S. (define_andreas)


Lesenswert?

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 ?

von Sebastian R. (sebastian_r569)


Lesenswert?

Du hast vergessen, die AD-Wandler aufzuführen, die du verwenden willst.

Ansonsten sollte das wohl schon damit möglich sein.

von Otto (Gast)


Lesenswert?

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

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

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

von Andreas S. (define_andreas)


Lesenswert?

die einzelnen Messwerte würde ich über I2C einlesen, oder liege ich da 
falsch ?

von Sebastian R. (sebastian_r569)


Lesenswert?

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?

von Andreas S. (define_andreas)


Lesenswert?

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 
!

von Sebastian R. (sebastian_r569)


Lesenswert?

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

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

... 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
von Sebastian R. (sebastian_r569)


Lesenswert?

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?

von Andreas S. (define_andreas)


Lesenswert?

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 ?

von Andreas S. (define_andreas)


Lesenswert?

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

von Sebastian R. (sebastian_r569)


Lesenswert?

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.

von Herakles (Gast)


Lesenswert?

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?

von Andreas S. (define_andreas)


Lesenswert?

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 
!

von Sebastian R. (sebastian_r569)


Lesenswert?

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?

von Wolfgang (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

Wolfgang schrieb:
> ... und dazu einen kleinen Arduino?

... und natürlich das SD  Karteninterface, z.B.
https://www.ebay.de/itm/311823238808

von Wolfgang (Gast)


Lesenswert?

... oder einfach soetwas für die SD-Karte:
https://www.ebay.de/itm/202464361598

von pumuggl (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

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

von Sebastian R. (sebastian_r569)


Lesenswert?

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

von Andreas S. (define_andreas)


Lesenswert?

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.

von Harry (Gast)


Lesenswert?

Wie wärs mit einem Arduino keine-Ahnung-aber-mit-XMega? Der hat 16 ADCs 
mit 12 Bit.

von Sebastian R. (sebastian_r569)


Lesenswert?

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.

von Thomas W. (goaty)


Lesenswert?

Ein ADC aber davor Multiplexer mit 8/16 Eingängen. Bei 100Hz sollte das 
gehen.

von Crazy Harry (crazy_h)


Lesenswert?

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.

von Andreas S. (define_andreas)


Lesenswert?

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
}

von Stefan F. (Gast)


Lesenswert?

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.

von Andreas S. (define_andreas)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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?

von pumuggl (Gast)


Lesenswert?

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

von Andreas S. (define_andreas)


Lesenswert?

Stefan ⛄ F. schrieb:
> Geht es bei dir um die USB Schnittstelle?

ja, es geht um die USB Schnittstelle

von Stefan F. (Gast)


Lesenswert?

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