Simultaneous reading of ADC ports?

Hi,

Still young and learning.

Is there a way to do simultaneous reading of lets say 13 analog ports and get them in number form without having to do doing port-lookup on every cycle?

Le code:

// Read the Analog ports
  int reading1 = analogRead(A0);
  float a0 = (reading1 * supply)/5;
  temperature1 = a0*1.6 ;
  int reading2 = analogRead(A1);
  float a1 = (reading2 * supply)/5;
  temperature2 = a1*1.6 ;
  int reading3 = analogRead(A2);
  float a2 = (reading3 * supply)/5;
  temperature3 = a2*1.6 ;
  int reading4 = analogRead(A3);
  float a3 = (reading4 * supply)/5;
  temperature4 = a3*1.6 ;
  int reading5 = analogRead(A4);
  float a4 = (reading5 * supply)/5;
  temperature5 = a4*1.6 ;
  int reading6 = analogRead(A5);
  float a5 = (reading6 * supply)/5;
  temperature6 = a5*1.6 ;
  int reading7 = analogRead(A6);
  float a6 = (reading7 * supply)/1.023;
  temperature7 = (a6 - 509)/6.45 ;
  int reading8 = analogRead(A7);
  float a7 = (reading8 * supply)/1.023;
  temperature8 = (a7 - 509)/6.45 ;
  int reading9 = analogRead(A8);
  int a8 = map(reading9, 0, 1023, lowPress1, highPress1);
  pressure1 = a8 * 1 ;
  int reading10 = analogRead(A9);
  int a9 = map(reading10, 0, 1023, lowPress2, highPress2);
  pressure2 = a9 * 1 ;
  int reading11 = analogRead(A10);
  int a10 = map(reading11, 0, 1023, lowPress3, highPress3);
  pressure3 = a10 * 1 ;
  int reading12 = analogRead(A11);
  int a11 = map(reading12, 0, 1023, lowPress4, highPress4);
  pressure4 = a11 * 1 ;
  int reading13 = analogRead(A12);
  float a12 = (reading13*supply)/5;
  BatteryVoltage = a12/31;

Designing a Datalogger with 248x64 LCD and SD card. The best update I'm getting on the LCD is about once every 3seconds with the SD card logging. Once every second without.

I can't publish the entire code since it's to long. Any tips or pointers are welcome!

Is there a way to do simultaneous reading of lets say 13 analog ports

With some custom hardware and 13 ADCs.
An AVR Arduino analogue conversion takes around 100 us - define what “simultaneous” means to you.

On the attached video you can see it running about 0.5-1fps. Any way to get it updating quicker?

Video

Snake____1: On the attached video you can see it running about 0.5-1fps. Any way to get it updating quicker?

Without seeing code? Guess.

AWOL: Without seeing code? Guess.

Hehe, I know. working on it...

Google drive link. "works for now..." INO

works for now...

For some people, maybe. Not for me.

I'm guessing you posted the code, there, though because you wanted google to help you. Why didn't you post your question there, too?

If you want help HERE, can you guess where you need to post your code?

PaulS:
For some people, maybe. Not for me.

I’m guessing you posted the code, there, though because you wanted google to help you. Why didn’t you post your question there, too?

If you want help HERE, can you guess where you need to post your code?

The message exceeds the maximum allowed length (9000 characters).

^^^^^^

Thats why… “I just linked the file on my Google drive account…”

Datalogger.ino (11.2 KB)

if (millis() - lastmillis <= 1000){  Errr…

Also, read up on arrays, before your code gets too big.

  if(digitalRead(23) == LOW && digitalRead(24) == LOW && digitalRead(25) == LOW && digitalRead(26) == LOW){
...
  else if(digitalRead(23) == HIGH && digitalRead(24) == LOW && digitalRead(25) == LOW && digitalRead(26) == LOW){
...
  else if(digitalRead(23) == LOW && digitalRead(24) == HIGH && digitalRead(25) == LOW && digitalRead(26) == LOW){
...
  else if(digitalRead(23) == HIGH && digitalRead(24) == HIGH && digitalRead(25) == LOW && digitalRead(26) == LOW){
...
  else if(digitalRead(23) == LOW && digitalRead(24) == LOW && digitalRead(25) == HIGH && digitalRead(26) == LOW){

Do you see the pattern here?

Here's a clue: 0b0001, 0b0010, 0b0011, 0b0100

23-24-25-26 are part of the same port, yes? PORTA? Good use for switch:case code:

portData = (PORTA & 0b00011110) >> 1; // 26-25-24-23
switch (portData){
case 0: // 0000
// code
break;
case 1: // 0001
// code
break;
:
: case 14: // 1110
//cod
break;
case 15;  // 1111
// code
break;
}

AWOL: Do you see the pattern here?

Here's a clue: 0b0001, 0b0010, 0b0011, 0b0100

Yes, switch case. Don't quite know how to integrate those yet. As I stated earlier, still learning ::) Regarding the delay(1000); this is only in the setup brackets "so only runs once?"

CrossRoads: 23-24-25-26 are part of the same port, yes? PORTA? Good use for switch:case code: portData = (PORTA & 0b00011110) >> 1; // 26-25-24-23 switch (portData)

When stating (PORTA & 0b00011110) >> 1; does this actually refer to the actual ports on the Mega? and what does the >> 1 do?

The code I quoted is not in setup(), so no, it doesn't run only once.

AWOL:
The code I quoted is not in setup(), so no, it doesn’t run only once.

Oh, right. But that’s only part of the RPM reading. This is read once every second to refresh the RPM value.

if (millis() - lastmillis <= 1000){  /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
 detachInterrupt(0);    //Disable interrupt when calculating
 rpm = rpmcount * 60;  /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/
 rpmcount = 0; // Restart the RPM counter
 lastmillis = millis(); // Uptade lasmillis
 attachInterrupt(0, rpmPin, FALLING); } //enable interrupt

Fixed the setup coding “thanks for the tip!”

 // Sensor setting ( 250kpa, 400kpa, 700kpa or 1.2Mpa )
  portData = (PORTA & 0b00011110) >> 1; // 26-25-24-23
  switch (portData){
  case 0: // 0000
  lowPress1 = -100; highPress1 = 150; lowPress2 = -100; highPress2 = 150;
  lowPress3 = -100; highPress3 = 150; lowPress4 = -100; highPress4 = 150; // code
  break;
  case 1: // 0001
  lowPress1 = -100; highPress1 = 300; lowPress2 = -100; highPress2 = 300;
  lowPress3 = -100; highPress3 = 150; lowPress4 = -100; highPress4 = 150;
  break;
  case 2: // 0010
  lowPress1 = -100; highPress1 = 150; lowPress2 = -100; highPress2 = 150;
  lowPress3 = -100; highPress3 = 300; lowPress4 = -100; highPress4 = 300;
  break;
  case 3: // 0011
  lowPress1 = -100; highPress1 = 300; lowPress2 = -100; highPress2 = 300;
  lowPress3 = -100; highPress3 = 300; lowPress4 = -100; highPress4 = 300;
  break;
  case 4: // 0100
  lowPress1 = -100; highPress1 = 150; lowPress2 = -100; highPress2 = 150;
  lowPress3 = -100; highPress3 = 600; lowPress4 = -100; highPress4 = 600;
  break;
  case 5: // 0101
  lowPress1 = -100; highPress1 = 600; lowPress2 = -100; highPress2 = 600;
  lowPress3 = -100; highPress3 = 150; lowPress4 = -100; highPress4 = 150;
  break;
  case 6: // 0110
  lowPress1 = -100; highPress1 = 600; lowPress2 = -100; highPress2 = 600;
  lowPress3 = -100; highPress3 = 600; lowPress4 = -100; highPress4 = 600;
  break;
  case 7: // 0111
  lowPress1 = -100; highPress1 = 300; lowPress2 = -100; highPress2 = 300;
  lowPress3 = -100; highPress3 = 600; lowPress4 = -100; highPress4 = 600;
  break;
  case 8: // 1000
  lowPress1 = -100; highPress1 = 600; lowPress2 = -100; highPress2 = 600;
  lowPress3 = -100; highPress3 = 300; lowPress4 = -100; highPress4 = 300;
  break;
  case 9: // 1001
  lowPress1 = -100; highPress1 = 150; lowPress2 = -100; highPress2 = 150;
  lowPress3 = 0; highPress3 = 1200; lowPress4 = 0; highPress4 = 1200;
  break;
  case 10: // 1010
  lowPress1 = 0; highPress1 = 1200; lowPress2 = 0; highPress2 = 1200;
  lowPress3 = -100; highPress3 = 150; lowPress4 = -100; highPress4 = 150;
  break;
  case 11: // 1011
  lowPress1 = -100; highPress1 = 300; lowPress2 = -100; highPress2 = 300;
  lowPress3 = 0; highPress3 = 1200; lowPress4 = 0; highPress4 = 1200;
  break;
  case 12: // 1100
  lowPress1 = 0; highPress1 = 1200; lowPress2 = 0; highPress2 = 1200;
  lowPress3 = -100; highPress3 = 300; lowPress4 = -100; highPress4 = 300;
  break;
  case 13: // 1101
  lowPress1 = -100; highPress1 = 600; lowPress2 = -100; highPress2 = 600;
  lowPress3 = 0; highPress3 = 1200; lowPress4 = 0; highPress4 = 1200;
  break;
  case 14: // 1110
  lowPress1 = 0; highPress1 = 1200; lowPress2 = 0; highPress2 = 1200;
  lowPress3 = -100; highPress3 = 600; lowPress4 = -100; highPress4 = 600;
  break;
  case 15: // 1111
  lowPress1 = 0; highPress1 = 1200; lowPress2 = 0; highPress2 = 1200;
  lowPress3 = 0; highPress3 = 1200; lowPress4 = 0; highPress4 = 1200;
  break;

But still grinding my head against the wall regarding the slow update while writing to SD.
I’m only writing the RPM value to the SD, for now although I want to add all the read values.

If I leave out this bit, i earn about 2seconds refresh time. Why?

// make a string for assembling the data to log:
  String dataString = "";
  // read three sensors and append to the string:
    dataString += String(rpm);
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();

if (millis() - lastmillis <= 1000){

This is read once every second

Have you checked that?

AWOL: Have you checked that?

This only affects the one value, rpm. The others are updated once every cycle? Or at least should?

It is a slow day.

if (millis() - lastmillis <= 1000)

Hint: if millis() == 1 and lastmillis == 0, is the difference less than or equal to 1000?

  portData = (PORTA & 0b00011110) >> 1; // 26-25-24-23

That should be PINA instead of PORTA.

jurs:
The ‘cost’ of doing a single analogRead() is roughly 120 microseconds on a 16 MHz “UNO” board.

So 13 times analogRead() is taking about 13*120= 1560 microseconds = less than 2 milliseconds.

If your code execution time is much more than 2 milliseconds doing 13 dtimes analogRead(), then the delayed execution is not caused by calling 13 times analogRead() function t. Your loss of time must be caused by differentfunctions in your program. Functions that you don’t show. So unfortunately nobody can see where you leave the time behind your expectations.

I got the file attached earlier? Anyways, here it is again… Removed all of the RPM parts, still slow

The problem is it takes about 3-5secs to cycle…

If i leave out this part it only takes one?:

// Record to SD
   if (rec == LOW && sd == 1){
// make a string for assembling the data to log:
  String dataString = "";
     dataString += String(rpm);
     dataString += ",";
     dataString += String(temperature1);
     dataString += ",";
     dataString += String(temperature2);
     dataString += ",";
     
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
   }
}

Datalogger.ino (9.74 KB)

Honestly, I think most of your time is being eaten up by the draw() function. Writing to an LCD screen is, I think, rather time consuming. And you are writing A LOT to the screen. Also, it looks like you’re writing the names of the variables (i.e. “pressure”) every iteration of loop(), which is grossly unnecessary.