Datenlogger 10Kanal

OP #6069795
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 ?
(Firma: @home) #6069842
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
#6069863
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?
Gast #6069877
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?
OP #6069881
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 
!
Gast #6069894
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.
Gast #6069932
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.
Gast #6069942
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.
(Firma: @home) #6070000
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
OP #6156973
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
}
Gast #6157013
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.
OP #6157421
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.
Gast #6157435
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren