Author Topic: Datalogging Arduino 6 analog inputs - programming  (Read 6799 times)

0 Members and 1 Guest are viewing this topic.

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Datalogging Arduino 6 analog inputs - programming
« on: April 25, 2016, 07:22:19 pm »
This is a "log" that will probably end up as a plea for help if/when I get stuck.

Parts:

The Arduino is a standard Uno V3
http://www.arduino.cc/en/Main/ArduinoBoardUno
Upon it is mounted an Adafruit data-logger
https://learn.adafruit.com/adafruit-data-logger-shield/shield-overview
This will use only the 6 analogue pins to make "relative" measurements.
These 6 pin are distributed as such:
1 for the temperature sensor, TMP 36 with the on board 5V.
https://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor
1 For the wind speed sensor; a DIY anemometer that registers 0 to 3.3V.
https://www.eevblog.com/forum/beginners/super-cheap-diy-anenometer-%28for-arduino%29/msg907964/#msg907964
4 that are connector to 4 load cells, with a DIY analogue amplifier.
The signal with no force is 1.5V, the max is 3V, the min is 0V.
https://www.eevblog.com/forum/beginners/filtering-an-output-analoque-rms/msg831675/#msg831675
This has been converted into a PCB and bodged to spec.
https://www.eevblog.com/forum/beginners/replacing-ferrite-beads-by-inductors/25/
All the components are supplied with a single 12V/0.9A powers supply.
The ground is common amongst all the parts.



I will be using the Adafruit example as inspiration for the code.
https://learn.adafruit.com/adafruit-data-logger-shield/light-and-temperature-logger
But my version will use mains power as the load cells in continuous usage burn about 80mA, for a total of about 200mA.
(I've got some ideas on power optimisation, but I'll need to spin a new board for that)

Sequence that I'm trying to code:

Read clock, save result as RTC
Read pin 0 1times over 1mS, save results as TMP.
Delay 4mS
Read pin 1 10times over 10mS, save results as WDS.
Delay 5mS
Read pin 2 5times over 5mS, save results as LC1.
Delay 5mS
Read pin 3 5times over 5mS, save results as LC2.
Delay 5mS
Read pin 4 5times over 5mS, save results as LC3.
Delay 5mS
Read pin 5 5times over 5mS, save results as LC4.
Delay 4930ms
Start loop again

Code

Code: [Select]
#define aref_voltage 3.3

int TmpPin = 0;
int TmpReading;

int WdsPin = 1;
int WdsReading;

int LC1Pin = 2;
int LC1Reading;

int LC2Pin = 3;
int LC2Reading;

int LC3Pin = 4;
int LC3Reading;

int LC4Pin = 5;
int LC4Reading;

void setup(void) {
  Serial.begin(9600);   

void loop(void) {
  TmpReading = analogRead(TmpPin);

  Serial.print("Temp1 = ");
  Serial.print(TmpReading);
 
  Delay(4)            // not sure to put (4) ar (5)

...
And so on... I'll keep on writing the code, please comment if you find anything weird...
 
« Last Edit: April 25, 2016, 11:35:37 pm by gildasd »
I'm electronically illiterate
 

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #1 on: April 25, 2016, 11:37:29 pm »
Trying to find a simple method to average certain of the sensors...
What I would like to smooth over 100ms:
Code: [Select]
  int wdsReading = analogRead(wdsPin);
 delay(10);
Not sure if I should do 10 readings with 10 delays, then add up and divide by 10. Or if there's code do this already done...

The full code right now:
Code: [Select]
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>

/* Memoire sketch01
 */

#define aref_voltage 3.3   // 3.3V is the ref voltage
#define LOG_INTERVAL  5000 // mills between entries (5s)
#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 3
#define greenLEDpin 4

// The analog pins that connect to the sensors
#define wdsPin 0           // analog 0
#define tmpPin 1           // analog 1
#define lc1Pin 2           // analog 2
#define lc2Pin 3           // analog 3
#define lc3Pin 4           // analog 4
#define lc4Pin 4           // analog 5


RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
 
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);
 
  while(1);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println();
 
#if WAIT_TO_START
  Serial.println("0"); //automatic start, no need to type in anything.
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
 
  // create a new file
  char filename[] = "CUBE1.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }
 
  if (! logfile) {
    error("couldnt create file");
  }
 
  Serial.print("Logging to: ");
  Serial.println(filename);

  Wire.begin(); 
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
 

  logfile.println("millis,time,temp,speed,sensor1,sensor2,sensor3,sensor");   
#if ECHO_TO_SERIAL
  Serial.println("millis,time,temp,speed,sensor1,sensor2,sensor3,sensor");
#if ECHO_TO_SERIAL// attempt to write out the header to the file
  if (logfile.writeError || !logfile.sync()) {
    error("write header");
  }
 
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
 
   // If you want to set the aref to something other than 5v
  //analogReference(EXTERNAL);
}

void loop(void)
{
  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
 
  digitalWrite(greenLEDpin, HIGH);

  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");   
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", "); 
#endif

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(now.get()); // seconds since 2000
  logfile.print(", ");
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
#if ECHO_TO_SERIAL
  Serial.print(now.get()); // seconds since 2000
  Serial.print(", ");
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL



  int wdsReading = analogRead(wdsPin);
 delay(10);
  int tmpReading = analogRead(tmpPin); 
 delay(10);
   // converting that reading to voltage, for 3.3v arduino use 3.3
  float voltage = tmpReading * 3.3 / 1024; 
  float temperatureC = (voltage - 0.5) * 100 ;

  int lc1Reading = analogRead(lc1Pin);
 delay(5);           // Short delay, buffered signal to ground via 10k resistor.
  int lc2Reading = analogRead(lc2Pin);
 delay(5);           // Short delay, buffered signal to ground via 10k resistor.
  int lc3Reading = analogRead(lc3Pin);
 delay(5);           // Short delay, buffered signal to ground via 10k resistor.
   int lc4Reading = analogRead(lc4Pin);
 delay(5);           // Short delay, buffered signal to ground via 10k resistor.
     
 
  logfile.print(", ");   
  logfile.print(wdsReading);
  logfile.print(", ");   
  logfile.println(temperatureC);
  logfile.print(", ");   
  logfile.print(lc1Reading);
  logfile.print(", ");   
  logfile.print(lc2Reading);
  logfile.print(", ");   
  logfile.print(lc3Reading);
  logfile.print(", ");   
  logfile.print(lc4Reading);       
#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(wdsReading);
  Serial.print(", ");   
  Serial.println(temperatureC);
  Serial.print(", ");   
  Serial.print(lc1Reading);
  Serial.print(", ");   
  Serial.print(lc2Reading);
  Serial.print(", ");   
  Serial.print(lc3Reading);
  Serial.print(", ");   
  Serial.print(lc4Reading);
#endif //ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);
}
« Last Edit: April 25, 2016, 11:43:19 pm by gildasd »
I'm electronically illiterate
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #2 on: April 25, 2016, 11:47:17 pm »
A simple method is moving average, for example you read the A/D on a specific
channel 16 times, summing them all as you read, then exit loop and / 16. Thats
a moving window average. You could do all the sensors this way in a single loop
for all. You haver to make sure your variable for the avg will not overflow, eg. size
it accordingly, word, double word, etc..

Regards, Dana.
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 
The following users thanked this post: gildasd

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #3 on: April 26, 2016, 12:01:48 am »
A simple method is moving average, for example you read the A/D on a specific
channel 16 times, summing them all as you read, then exit loop and / 16. Thats
a moving window average. You could do all the sensors this way in a single loop
for all. You haver to make sure your variable for the avg will not overflow, eg. size
it accordingly, word, double word, etc..

Regards, Dana.
I was thinking about something along those lines... More code but simple.
Do you have an example of code that you find well written?

Thanks!
I can't distinguish stuff done by a greybeard from a cat walking across the keyboard...
« Last Edit: April 26, 2016, 12:17:02 am by gildasd »
I'm electronically illiterate
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #4 on: April 26, 2016, 10:50:39 am »
I don't have an example, but basically use a for loop, say for 16
samples, and each pass thru the loop -

1) Read sensor pin, add to it the value in its array location, store back into array
2) Do the next sensor.........
3) Do this for 15 times
4) Do one more time for last sample but add step after array update of dividing the
array value by 16. Just use an if statement to test index = 15 in for loop to add the
step. For loop index goes from 0 to 15.
5) Exit loop

You are done. Size of array elements such that 16 full scale values do not overflow
the array element. For example if array element a word, then A/D must be no more than
12 bits.

Regards, Dana.
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 
The following users thanked this post: gildasd

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #5 on: April 26, 2016, 01:51:59 pm »
Problem is that I have 3 sensor types with different characteristics (impedance mostly) and different sampling needs...
I'm going to try to do what you say, but sensor by sensor...Not sure about this!
« Last Edit: April 26, 2016, 03:40:24 pm by gildasd »
I'm electronically illiterate
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #6 on: April 26, 2016, 04:43:11 pm »
If each sensor needs different driving characteristics then use f() calls inside for() loop
to call custom read code for each respective sensor.

If you are polling the sensors the disadvantage is the latency that cause getting reads from one to the
next sensor. Alternative is, if sensor supports it, to set them up as interrupt driven reads. Then the
ISR routine handles the code or better yet, simply sets a flag in ISR and then that flag gets tested in main()
for processing the read.

Regards, Dana.
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 
The following users thanked this post: gildasd

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #7 on: April 26, 2016, 07:06:04 pm »
If each sensor needs different driving characteristics then use f() calls inside for() loop
to call custom read code for each respective sensor.

If you are polling the sensors the disadvantage is the latency that cause getting reads from one to the
next sensor. Alternative is, if sensor supports it, to set them up as interrupt driven reads. Then the
ISR routine handles the code or better yet, simply sets a flag in ISR and then that flag gets tested in main()
for processing the read.

Regards, Dana.

I think there is a problem... The code won't compile. Even Adafruits unmodified code does not pass the verification stage  :palm:
I have to check my version and the libraries, not sure what else...
On the positive side, I did another simple serial code and tested the sensors, those work.

Error message:
Code: [Select]
Arduino: 1.6.5 (Windows 7), Board: "Arduino Uno"

Build options changed, rebuilding all

sketch_memoire02:96: error: unterminated #if
sketch_memoire02:94: error: unterminated #if
sketch_memoire02.ino: In function 'void setup()':
sketch_memoire02:93: error: expected '}' at end of input
unterminated #if

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
I don't get it, the lines do have "}" termination...  |O
I'm electronically illiterate
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #8 on: April 26, 2016, 07:10:02 pm »
They have a #endif associated with them ?

Regards, Dana.
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 
The following users thanked this post: gildasd

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #9 on: April 26, 2016, 07:20:59 pm »
They have a #endif associated with them ?

Regards, Dana.
No, that's weird, you'd think Miss Ada would not leave stuff out on a code example for a product she sells...
i'm checking if the the libraries and the shield has any weird setup quirks...
I'm electronically illiterate
 

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #10 on: April 26, 2016, 10:18:08 pm »
They have a #endif associated with them ?

Regards, Dana.
No, that's weird, you'd think Miss Ada would not leave stuff out on a code example for a product she sells...
i'm checking if the the libraries and the shield has any weird setup quirks...
I think I've found most of the problems:
- Real time clock must be activated.
- Windows in Dutch, path of elements in library in English = conflict.
I'm electronically illiterate
 

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #11 on: April 26, 2016, 11:44:38 pm »
IT IS ALIVE
Installed a new version of the IDE, and before loading the 1st file, changed the address in the option menu.
Restarted, and began uploading more and more complex programs.
The big mistake was renaming the "log" file, it makes the poor thing unstable.
Code: [Select]
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

// A simple data logger for the Arduino analog pins

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 2
#define greenLEDpin 3

// The analog pins that connect to the sensors
#define tempPin 0           // analog 0
#define windPin 1                // analog 1
#define BANDGAPREF 14            // special indicator that we want to measure the bandgap

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
#define bandgap_voltage 1.1      // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
 
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println();
 
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
 
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
 
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }
 
  if (! logfile) {
    error("couldnt create file");
  }
 
  Serial.print("Logging to: ");
  Serial.println(filename);

  // connect to RTC
  Wire.begin(); 
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
 

  logfile.println("millis,stamp,datetime,temp,wind,vcc");   
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,temp,wind,vcc");
#endif //ECHO_TO_SERIAL
 
  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
}

void loop(void)
{
  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
 
  digitalWrite(greenLEDpin, HIGH);
 
  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");   
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", "); 
#endif

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(now.unixtime()); // seconds since 1/1/1970
  logfile.print(", ");
  logfile.print('"');
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"');
#if ECHO_TO_SERIAL
  Serial.print(now.unixtime()); // seconds since 1/1/1970
  Serial.print(", ");
  Serial.print('"');
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print('"');
#endif //ECHO_TO_SERIAL

  analogRead(tempPin);
  delay(10);
  int tempReading = analogRead(tempPin); 
 
  analogRead(windPin);
  delay(10);
  int windReading = analogRead(windPin);   
 
  // converting that reading to voltage, for 3.3v arduino use 3.3, for 5.0, use 5.0
  float voltage = tempReading * aref_voltage / 1024; 
  float temperatureC = (voltage - 0.5) * 100 ;
 
  logfile.print(", ");   
  logfile.print(temperatureC);
  logfile.print(", ");   
  logfile.print(windReading);
#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(temperatureC);
  Serial.print(", ");   
  Serial.print(windReading);
#endif //ECHO_TO_SERIAL

  // Log the estimated 'VCC' voltage by measuring the internal 1.1v ref
  analogRead(BANDGAPREF);
  delay(10);
  int refReading = analogRead(BANDGAPREF);
  float supplyvoltage = (bandgap_voltage * 1024) / refReading;
 
  logfile.print(", ");
  logfile.print(supplyvoltage);
#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(supplyvoltage);
#endif // ECHO_TO_SERIAL

  logfile.println();
#if ECHO_TO_SERIAL
  Serial.println();
#endif // ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
 
  // blink LED to show we are syncing data to the card & updating FAT!
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  digitalWrite(redLEDpin, LOW);
 
}

I'm electronically illiterate
 

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #12 on: May 01, 2016, 09:23:00 am »
https://www.arduino.cc/en/Tutorial/Smoothing
Trying to add this to my code...

I had some problems solving stuff... A buffer at the outputs is needed to stop most problems: live and learn!

Code: [Select]
/*

  Smoothing

  Reads repeatedly from an analog input, calculating a running average
  and printing it to the computer.  Keeps ten readings in an array and
  continually averages them.

  The circuit:
    * Analog sensor (potentiometer will do) attached to analog input 0

  Created 22 April 2007
  By David A. Mellis  <dam@mellis.org>
  modified 9 Apr 2012
  by Tom Igoe
  http://www.arduino.cc/en/Tutorial/Smoothing

  This example code is in the public domain.


*/


// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

void setup() {
  // initialize serial communication with computer:
  Serial.begin(9600);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  Serial.println(average);
  delay(1);        // delay in between reads for stability
« Last Edit: May 01, 2016, 10:14:06 am by gildasd »
I'm electronically illiterate
 

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #13 on: May 01, 2016, 05:07:29 pm »
I've been trying to solve this for a few days by myself, but I can't do it on my own...
I'm probably missing something basic/silly.
I am using 2 Adafruit datalogging shields to log 2 sets of 4 independent load cells and I'm stumbling at the last hurdle...
The Aduinos Uno are stock, no jumpers.

When all the cells are plugged in, the shields lock up when the green LED is lit (that's during the write stage of the loop).


The load cell circuit emits 1.5V with no load. A positive load makes them go towards 0, negative load makes them go toward 3.3V.

The code I am using is based on the one provided by Adafruit, simply modded for the 6 analogue signals:
Code: [Select]
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

// A simple data logger for the Arduino analogue pins

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 2
#define greenLEDpin 3

// The analog pins that connect to the sensors
#define tempPin 0                // analog 0
#define windPin 1                // analog 1
#define cube2Pin 2               // analog 2
#define cube3Pin 3               // analog 3
#define cube4Pin 4               // analog 4
#define cube5Pin 5               // analog 5
#define BANDGAPREF 14            // special indicator that we want to measure the bandgap

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
#define bandgap_voltage 1.1      // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
 
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println();
 
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
 
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
 
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
 
  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }
 
  if (! logfile) {
    error("couldnt create file");
  }
 
  Serial.print("Logging to: ");
  Serial.println(filename);

  // connect to RTC
  Wire.begin(); 
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
 

  logfile.println("millis,stamp,datetime,temp,wind,cube2,cube3,cube4,cube5,vcc");   
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,temp,wind,cube2,cube3,cube4,cube5,vcc");
#endif //ECHO_TO_SERIAL
 
  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
}

void loop(void)
{
  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
 
  digitalWrite(greenLEDpin, HIGH);
 
  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");   
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", "); 
#endif

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(now.unixtime()); // seconds since 1/1/1970
  logfile.print(", ");
  logfile.print('"');
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
  logfile.print('"');
#if ECHO_TO_SERIAL
  Serial.print(now.unixtime()); // seconds since 1/1/1970
  Serial.print(", ");
  Serial.print('"');
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
  Serial.print('"');
#endif //ECHO_TO_SERIAL

  analogRead(tempPin);
  delay(10);
  int tempReading = analogRead(tempPin); 
 
  analogRead(windPin);
  delay(10);
  int windReading = analogRead(windPin);   

  analogRead(cube2Pin);
  delay(10);
  int cube2Reading = analogRead(cube2Pin);   

  analogRead(cube3Pin);
  delay(10);
  int cube3Reading = analogRead(cube3Pin);   

  analogRead(cube4Pin);
  delay(10);
  int cube4Reading = analogRead(cube4Pin);
 
  analogRead(cube5Pin);
  delay(10);
  int cube5Reading = analogRead(cube5Pin); 
 
  // ADC temp reading to centigrade
  float voltage0 = tempReading * 3.3 / 1024; 
  float temperatureC = (voltage0 - 0.5) * 100 ;
 
  logfile.print(", ");   
  logfile.print(temperatureC);
  logfile.print(", ");   
  logfile.print(windReading);
  logfile.print(", ");   
  logfile.print(cube2Reading);
  logfile.print(", ");   
  logfile.print(cube3Reading);
  logfile.print(", ");   
  logfile.print(cube4Reading);
  logfile.print(", ");   
  logfile.print(cube5Reading);     
#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(temperatureC);
  Serial.print(", ");   
  Serial.print(windReading);
  Serial.print(", ");   
  Serial.print(cube2Reading);
  Serial.print(", ");   
  Serial.print(cube3Reading);
  Serial.print(", ");   
  Serial.print(cube4Reading);
  Serial.print(", ");   
  Serial.print(cube5Reading);
#endif //ECHO_TO_SERIAL

  // Log the estimated 'VCC' voltage by measuring the internal 1.1v ref
  analogRead(BANDGAPREF);
  delay(10);
  int refReading = analogRead(BANDGAPREF);
  float supplyvoltage = (bandgap_voltage * 1024) / refReading;
 
  logfile.print(", ");
  logfile.print(supplyvoltage);
#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(supplyvoltage);
#endif // ECHO_TO_SERIAL

  logfile.println();
#if ECHO_TO_SERIAL
  Serial.println();
#endif // ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
 
  // blink LED to show we are syncing data to the card & updating FAT!
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  digitalWrite(redLEDpin, LOW);
 
}
Without the cells plugged in, and/or the signal cable between the shield and the load cells not plugged in, the shield works...
I don't know if the problem is code, Arduino or having to buffer the signal...

Any help/pointers would be greatly appreciated.
I'm electronically illiterate
 

Offline gildasdTopic starter

  • Frequent Contributor
  • **
  • Posts: 935
  • Country: be
  • Engineering watch officer - Apprentice Officer
    • Sci-fi Meanderings
Re: Datalogging Arduino 6 analog inputs - programming
« Reply #14 on: May 01, 2016, 07:24:42 pm »
I put an opamp buffer between the source the shield...

It does not hang up any more, but acts weird...
When I reset the shield:
- On the shield side of the buffer: 3.65V
- On the amplifier side 1.3V (Ok).
It's like the arduino is trying to push a charge back across the buffer and hitting it's +VCC
ADC's are not meant to do that!
I'm electronically illiterate
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf