0

I have an 16 bit ADC7606. It is in parallel mode. I have a working sketch that allows me to read 8 channels, convert the 16 bit integer to decimal and then serial prints to monitor. I would like to increase the frequency of the sampling rate. The serial monitor can not keep up with a sampling rate faster than 40millis. The Due is connected via USB on COM3.

How do I log the data to a file on my laptop/computer?

All and any help greatly appreciated.

Code below,

#include <EnableInterrupt.h>

#define BUSY 3
#define RD 4  //RD+CS tied together
#define RESET 5
#define CONVST 6 //CONVSTA+CONVSTB soldered together on the board
#define RANGE 7

#define DB0 38
#define DB1 39
#define DB2 40
#define DB3 41
#define DB4 42
#define DB5 43 
#define DB6 44
#define DB7 45
#define DB8 46
#define DB9 47
#define DB10 48
#define DB11 49
#define DB12 50
#define DB13 51
#define DB14 52
#define DB15 53

// declare rawData as an array of 16 integers
int rawData[16];

void setup() {

  enableInterrupt(BUSY, ISR_, FALLING);

  pinMode(RESET, OUTPUT);
  pinMode(CONVST, OUTPUT);
  pinMode(RD, OUTPUT);
  pinMode(RANGE, OUTPUT);
  pinMode(BUSY, INPUT);

  Serial.begin(9600);

  //reset ADC to begin conversion 
  digitalWrite(RESET, HIGH);
  delayMicroseconds(10);
  digitalWrite(RESET, LOW);

  digitalWrite(CONVST, LOW);  
  digitalWrite(RD, HIGH);
  digitalWrite(RANGE, HIGH);
  digitalWrite(BUSY, LOW);  

  delayMicroseconds(1000);

}

void loop() {

  disableInterrupt(BUSY);

  delayMicroseconds(40000); 
  digitalWrite(CONVST, LOW);
  delayMicroseconds(10); 
  digitalWrite(CONVST, HIGH);
  enableInterrupt(BUSY, ISR_, FALLING);

}

void ISR_ ()  {

  //Serial.print(millis());
  //Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH);
  Serial.print(",");

  delayMicroseconds(1);
  digitalWrite(RD, LOW);
  delayMicroseconds(1);
  readDBpins(); // do read
  digitalWrite(RD, HIGH); 

  Serial.println(" ");

}

void readDBpins()
{
  rawData[0] = digitalRead(DB15);
  //Serial.print (rawData[0]);
  if (rawData[0] > 0) {rawData[0] = 32768;} 
  rawData[1] = digitalRead(DB14);  
  //Serial.print (rawData[1]);
  if (rawData[1] > 0) {rawData[1] = 16384;}
  rawData[2] = digitalRead(DB13);
  //Serial.print (rawData[2]);
  if (rawData[2] > 0) {rawData[2] = 8192;}
  rawData[3] = digitalRead(DB12);
  //Serial.print (rawData[3]);
  if (rawData[3] > 0) {rawData[3] = 4096;}
  rawData[4] = digitalRead(DB11);
  //Serial.print (rawData[4]);
  if (rawData[4] > 0) {rawData[4] = 2048;}
  rawData[5] = digitalRead(DB10);
  //Serial.print (rawData[5]);
  if (rawData[5] > 0) {rawData[5] = 1024;}
  rawData[6] = digitalRead(DB9);
  //Serial.print (rawData[6]);
  if (rawData[6] > 0) {rawData[6] = 512;}
  rawData[7] = digitalRead(DB8);
  //Serial.print (rawData[7]);
  if (rawData[7] > 0) {rawData[7] = 256;}
  rawData[8] = digitalRead(DB7);
  //Serial.print (rawData[8]);
  if (rawData[8] > 0) {rawData[8] = 128;}
  rawData[9] = digitalRead(DB6);
  //Serial.print (rawData[9]);
  if (rawData[9] > 0) {rawData[9] = 64;}
  rawData[10] = digitalRead(DB5);
  //Serial.print (rawData[10]);
  if (rawData[10] > 0) {rawData[10] = 32;}
  rawData[11] = digitalRead(DB4);
  //Serial.print (rawData[11]);
  if (rawData[11] > 0) {rawData[11] = 16;}
  rawData[12] = digitalRead(DB3);
  //Serial.print (rawData[12]);
  if (rawData[12] > 0) {rawData[12] = 8;}
  rawData[13] = digitalRead(DB2);
  //Serial.print (rawData[13]);
  if (rawData[13] > 0) {rawData[13] = 4;}
  rawData[14] = digitalRead(DB1);
  //Serial.print (rawData[14]);
  if (rawData[14] > 0) {rawData[14] = 2;}
  rawData[15] = digitalRead(DB0);
  // Serial.print (rawData[15]);
  if (rawData[15] > 0) {rawData[15] = 1;}

  Serial.print (rawData[0]+rawData[1]+rawData[2]+rawData[3]+rawData[4]+rawData[5]+rawData[6]+rawData[7]+rawData[8]+rawData[9]+rawData[10]+rawData[11]+rawData[12]+rawData[13]+rawData[14]+rawData[15]);
}
  • Its name is a AD7606 (without the C)? analog.com/en/products/ad7606.html – Jot Sep 14 '18 at 16:37
  • 2
    why 9600 baud? try 921600 baud – Juraj Sep 14 '18 at 16:50
  • Other Serial terminal programs may have a function to save the received data to a file. Try some of them. And - since the Serial interface doesn't keep up - as Juraj wrote increase the baudrate, so that the data transfer is done with higher speed. – chrisl Sep 14 '18 at 21:21
  • Thanks peeps. I read that anything over 115200 baud is not effective. 115200 is the usual rate I use. Serial Monitor cannot display the readings with anything faster than a 40millis sampling rate so I cannot do what I usually do and copy and paste to file as there is nothing there to copy. – Microk Sep 15 '18 at 10:26
  • @Juraj and chrisl 921600 baud and anything above 250000 prints gibberish. i now have a pyserial log script but it still bottlenecks, although now at 1.5millis, which is good but not good enough. I now know I messed up the 2's complement conversion in my arduino sketch but even with that commented out it still bottlenecks. – Microk Sep 19 '18 at 22:02
2

You can use python on the command line to log your serial monitor output. This is described here. The script below has a baud rate of 250000 but can be set according to how you program your arduino.

from time import sleep
import serial

# Change port and baud rate to match your setup
ser = serial.Serial('/dev/ttyACM0', 250000) # Establish the connection on a specific port

counter = 32 # Below 32 everything in ASCII is gibberish

while True:
     counter +=1
     ser.write(str(chr(counter))) # Convert the decimal number to ASCII then send it to the Arduino
     print(ser.readline()) # Read the newest output from the Arduino
     sleep(.1) # Delay for one tenth of a second
     if counter == 255:
         counter = 32

Script from here. You must put in your appropriate port and baud rate. This Mathworks link describes how to find your port number.

  • In windows look in Device Manager under USB Serial Port.
  • In linux or OSX open a terminal and search with ls /dev/* or ls /dev/tty*. You can | grep <search> on the same line to search usb or ACM

This is a discussion about maximum baud rate. I have gone up to 250000 on the Due's programming port but you can go faster using the native port. You may also be limited by your computer usb though unlikely. 480 Mbit/s max for USB 2.0.

The Arduino Due has two USB ports available. The Native USB port (which supports CDC serial communication using the SerialUSB object) is connected directly to the SAM3X MCU. The other USB port is the Programming port. It is connected to an ATMEL 16U2 which acts as a USB-to-Serial converter. This Programming port is the default for uploading sketches and communicating with the Arduino.

The USB-to-serial converter of the Programming port is connected to the first UART of the SAM3X. It's possible to communicate over this port using the "Serial" object in the Arduino programming language.

The USB connector of the Native port is directly connected to the USB host pins of the SAM3X. Using the Native port enables you to use the Due as a client USB peripheral (acting as a mouse or a keyboard connected to the computer) or as a USB host device so that devices can be connected to the Due (like a mouse, keyboard, or an Android phone). This port can also be used as a virtual serial port using the "SerialUSB" object in the Arduino programming language.

From the Arduino Due guide you can switch Serial.print to SerialUSB.print, same with other serial functions like println. Then if you plug your usb into the Native port you can read off that port at a higher baud rate. You must also initialize the SerialUSB,

SerialUSB.begin(2000000);    // Initialize Native USB port
while(!SerialUSB);           // Wait until connection is established

It shouldn't matter what you set the baud rate at on the native port, it will run at the maximum bus speed but from what I know it has to be set regardless.

When running on the command line you can use > to send the output to a log file.

For example,

python serial_log.py > out.txt
  • Thanks for the detailed answer. I've now got a basic sketch output being read by python and displayed in a command prompt python window. I can data log now thanks to the path you set me on, using a different serial logger script I found here github.com/diegoherranz/serial-logger – Microk Sep 18 '18 at 21:12
  • I could not get the serial_log.py that you suggested to work. I still have the same problem though, logging 8 columns of 16bit integers at a faster rate than 40millis. Do you think your suggestion will be able to log any faster? – Microk Sep 18 '18 at 21:26
  • I believe the code provided only works with python2. If you got something else similar to work thats just as well. Raising your baud rate will increase your transmission speed, notes on baud rate. The python script may enable baud rates that the arduino ide does not support. If your problem is in fact with the speed of an arduino function you may look into an alternative, this is an example for the analogRead function. – jmb2341 Sep 19 '18 at 5:52
  • 1
    Use the native port and increase the baud rate further. Replace Serial.print with SerialUSB.print, see the updated response. – jmb2341 Sep 19 '18 at 22:06
  • 1
    Make sure you are only accessing the serial from one location. If you have the Arduino ide accessing the monitor then you may not be able to use a script to access it, or if you have two terminal windows open. Also I would still probably program via the programming port, then switch over to the native port for reading. Hope it helps! – jmb2341 Sep 20 '18 at 1:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.