Combining code datalogger and monstermux 32

Hello all,
I'm having trouble to put together 2 codes from 2 different shields... I have an arduino Duemilanove, a datalogger from adafruit and a 32 analogue shield from critical velocity.
the question is how to combine the two standard code in one!
I'm a beginner in arduino but know my electronics! Coding is not my best part but eager to learn from anyone!
here is the part from the "monstermux 32ch analogue shield";

 [color=red]/* MonsterMux32 Demo Code
   Critical Velocity 2009
   This code selects an analog channel and prints the value to the serial port.
   For more information, visit www.criticalvelocity.com/mmux32
*/

int sensorValue;
char muxch = 23;  // change this to the channel number you wish to read.

void setup() {
  // These 6 pins control which analog channel is connected to the Analog Input 0 on the Arduino.
  pinMode(8, OUTPUT);  
  pinMode(9, OUTPUT);  
  pinMode(10, OUTPUT);  
  pinMode(11, OUTPUT);  
  pinMode(12, OUTPUT);  
  pinMode(13, OUTPUT); 
  Serial.begin(9600); 
}

void loop() {
  // read the value from the sensor:
  set_mux(muxch);
  
  // Analog 0 is now connected to input set by muxch.
  sensorValue = analogRead(0);    
  
  Serial.println(sensorValue);
  delay(10);                  
}

// The following function selects the channel to be read.
// using PORTB directly is not really recommended for the Arduino environment. 
// Feel free to modify the code to avoid direct writes to PORTB.

void set_mux(char channel) {
  // sets mux to read selected channel.
  if (channel < 32) {
    // valid channels are 0-31
    PORTB = (PORTB & 0xC0) | channel;
  }
}
[/color]

and here the code from the datalogger;

 [color=green]#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 photocellPin 0           // analog 0
#define tempPin 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,light,temp,vcc");    
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,light,temp,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(photocellPin);
  delay(10); 
  int photocellReading = analogRead(photocellPin);  
  
  analogRead(tempPin); 
  delay(10);
  int tempReading = analogRead(tempPin);    
  
  // 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 ;
  float temperatureF = (temperatureC * 9 / 5) + 32;
  
  logfile.print(", ");    
  logfile.print(photocellReading);
  logfile.print(", ");    
  logfile.print(temperatureF);
#if ECHO_TO_SERIAL
  Serial.print(", ");   
  Serial.print(photocellReading);
  Serial.print(", ");    
  Serial.print(temperatureF);
#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);
  
}
[/color]

I tried a few things like combining the void setup and replacing the two void loop by naming them void loop_code 1(); and void loop_code2();
this was not working for me and many errors appeared!

by the way: the code for the light sensor and temperature does not have tobe in there, I want to have a blank shield where I can just put my analogue inputs into it.

My goal is to use this datalogger for monitoring many K-type thermocouples using the AD595 thermocouple chip!

Please, if there's anyone who can help it's very much appreciated!

thank's

rjbtd1

In my experience, as a hack programmer, the only way to really combine two pieces of code like that is to completely understand how each piece works. Once you fully understand what's happening it will start to become apparent which pieces you can keep and what you need to rewrite. It isn't so much about bashing two sketches together as combining two concepts. Just read them over and over and make experimental changes until they make sense. You don't need some of the code on the logger so work on eliminating that as a means to understanding how logging works.

One little tip. I notice that the logging sketch uses delay() for timing when to log. That won't be acceptable when you combine the two. So now there's another sketch that you will need to digest - blink without delay. The concept behind it will be needed.

Hello Jimmy60

Thanks a lot for the rapid reply!!
I also think i have to invest in learning to code and really understand the code that is used in the two sketches. (no better way to learn then just tinkering about)

I have all made the hardware for using my little project and just can't wait to see it work! the good thing is is that it's a hobby and hope to learn a lot from this!

Again, thanks for your tip and fast reply!
Richard

I also think i have to invest in learning to code and really understand the code that is used in the two sketches. (no better way to learn then just tinkering about)

You can think about it all day long, but you won't actually learn anything until you start making your own mistakes, figuring out that they are mistakes, why they are mistakes, and correcting them.

Hey Paul... You Promised you wouldn't share my little secret to success...

Bob

Hi,
You mention the following;

I'm a beginner in arduino but know my electronics! Coding is not my best part but eager to learn from anyone!

I am wondering if what you are attempting to do is initially to complex for you, considering you are new to Arduino and maybe programming in general.
My question to you is, have you played around, experimented with the examples?
Doing so will give you the best possible understanding in a shorter time, learning from experience and experimenting.

It seems you have tried by combining the two setup sections and doing some other things.
You really will need to understand each program in its own right and then be able to pull them apart to re-combine into one program.
I personally would not write the programs like you have presented, I find it difficult to read, especially with the comments left justified and on separate lines.
I make use of functions to break the code down into relevant parts, I also break larger code sections into separate source/header files.
Doing this make it far easier to read and develop larger code.

I do not want to dampen your enthusiasm, but I am thinking and concerned that you may well be overwhelmed by trying and ending up disheartened with failure.
I have code that will do what you want that I have developed, but I can tell you it does take time to develop, time to sit down and learn.
For me or others giving you code, I would guess you will not learn so much, what do you think?
Can I encourage you to try merging the code of two smaller projects initially.
I would be keen to hear of your progress.

One last question, check that your Adafruit data logger has a hardware based rtc on board, as your code needs this?

rockwallaby.

Rockwallaby,

Thanks a million for your post! it"s been a wile since working on my Arduino Thermocouple project because of busy with work but I'm back again:)
I"m still eager to learn to write my own code and therefore have bought a Cooking book from arduino with many example codes in there with explanatory text (very handy).
The code of "monstermux" I have learend to understand how it works and the same for the Datalogger however the datalogger code is a bit more complex and don't undrstand all of it yet.
There are indeed a few elements in there that can be left out.
Just to have the compleet picture I have printed out everything and manualy "cut and past" what I think I need in the right order.
Still no succes though but I have the feeling I get somewere, it needs more studying and understanding how to combine code.
I will sure let you know when I'm done and have it up and running! (hopefully..)

thanks,

rjbtd1

Well, this is what I have done so far: the code is combined and compiled without errors but doesn't mean it's a good one (not tested on the hardware yet) I have my doubts over the Delay entries as mentioned by jimmy60 and wondering if I need to use another type of Delay() to overcome this problem I thought of using the myDelay function but like to know from someone if it's a good option or not? well here it is:

/* MonsterMux32 Demo Code
   Critical Velocity 2009
   This code selects an analog channel and prints the value to the serial port.
   For more information, visit www.criticalvelocity.com/mmux32
*/

int sensorValue;
char muxch = 23;  // change this to the channel number you wish to read.

#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
          // analog 0
                // 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() {
setupmux();
setuplogger();
}

void loop(){
loopmux();
looplogger();
}

void setupmux(){
  // These 6 pins control which analog channel is connected to the Analog Input 0 on the Arduino.
  pinMode(8, OUTPUT);  
  pinMode(9, OUTPUT);  
  pinMode(10, INPUT);  
  pinMode(11, OUTPUT);  
  pinMode(12, OUTPUT);  
  pinMode(13, OUTPUT); 
  Serial.begin(9600); 
}

void setuplogger()
{
  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,light,temp,vcc");    
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,light,temp,vcc");
#endif //ECHO_TO_SERIAL
 
  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
}






void loopmux() {
  // read the value from the sensor:
  set_mux(muxch);
  
  // Analog 0 is now connected to input set by muxch.
  sensorValue = analogRead(0);    
  
  Serial.println(sensorValue);
  delay(10);                  
}

// The following function selects the channel to be read.
// using PORTB directly is not really recommended for the Arduino environment. 
// Feel free to modify the code to avoid direct writes to PORTB.

void set_mux(char channel) {
  // sets mux to read selected channel.
  if (channel < 32) {
    // valid channels are 0-31
    PORTB = (PORTB & 0xC0) | channel;
  }
}





void looplogger()
{
  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

  
  
  // converting that reading to voltage, for 3.3v arduino use 3.3, for 5.0, use 5.0
  

  // 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);
  
}

Any coment is welcome!

Any coment is welcome!

Get rid of the delay()s. All of them. None are needed, and they WILL throw off your logging times.

Use millis() to determine if it is time to log again, based on the saved time last time you logged.

Thanks PaulS, will do right away! Busy working on the hardware at this moment!

rjbtd1

So far so good on the logging side, now I have to find a way to read all channels at the same time on my "serial monitor".
For the moment it only reads channel 23 and obviously not enough!

Any ideas?

rjbtd1