Pages: [1]   Go Down
Author Topic: need another set of eyes for Blink Without Delay  (Read 568 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 538
Posts: 27088
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Gang,
Have a custom 1284P board with a bunch of temperature sensors accessed via SPI with individual SS lines.
IDE 1.0.3
Want to read them all every so many seconds & send data out.
When I comment out one section of code, it works great.
When it is, the time checking is totally hosed.
Any ideas?  This has me totally stumped.

Hosed time check results

time check 5000
time check 4294906767
time check 4294901592
time check 4294841247
time check 4294775716
time check 4294710190
time check 4294705011
time check 4294644667
time check 4294579136
time check 4294513609

Result seems to be going  backwards?!?

Code:
/* 
 Code to read 15 MAX31865 RTD chips via ATMega1284P & send data out via Serial port using FTDI chip.
 */

#include <SPI.h>

// declare chip selects
// 0, 1 are serial pins
byte ss0 = 2;
byte ss1 = 3;
byte ss2 = 4;
byte ss3 = 5;
byte ss4 = 6;
byte ss5 = 7;
byte ss6 = 8;
byte ss7 = 9;
byte ss8 = 10;
// 11, 12, 13 are SPI pins
byte ss9 = 14;
byte ss10 = 15;
byte ss11 = 16;
byte ss12 = 17;
byte ss13 = 18;
byte ss14 = 19;


byte SSarray[] = {
  2,3,4,5,6,7,8,9,10,14,15,16,17,18,19};

// 20-31 not used

//declare variables
// registers
byte config_read = 0x00;
byte config_write = 0x80;
byte RTD_MSBs = 0x01;
byte RTD_LSBs = 0x02;
byte High_Fault_Threshold_MSB_read = 0x03; // 83h FFh R/W
byte High_Fault_Threshold_MSB_write = 0x83;
byte High_Fault_Threshold_LSB_read = 0x04; // 84h FFh R/W
byte High_Fault_Threshold_LSB_write = 0x84;
byte Low_Fault_Threshold_MSB_read = 0x05; // 85h 00h R/
byte Low_Fault_Threshold_MSB_write = 0x85;
byte Low_Fault_Threshold_LSB_read = 0x06; // 86h 00h R/W
byte Low_Fault_Threshold_LSB_write = 0x86;
byte Fault_Status_read = 0x07; // 00h R

byte Readarray[120] ; // 8 x 15 RTDs, start on 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112

byte x; // counter
byte y; // counter

unsigned long currentTime;
unsigned long endTime;
unsigned long elapsedTime;
//unsigned long duration = 55; // conversion time, milliseconds
unsigned long duration = 5000UL; // Set longer for degug, keep PC serial port from getting swamped

void setup(){
  // set up output pins
  for (x=0; x<15; x=x+1){
    pinMode(SSarray[x], OUTPUT);
  }

  Serial.begin(115200);
  SPI.begin(); // default 4 MHz

} // end setup

void loop(){
  currentTime = millis();
  elapsedTime = currentTime - endTime;
  if ( elapsedTime >= duration){ // report on prior sample
    endTime = endTime + duration; // set for next time check
    Serial.print ("time check ");
    Serial.println (elapsedTime);

    // ****  Time check works correctly if this section is commented out ****
    // loop within a loop - outer is a chip, inner is the 8 registers
    for (x = 0; x<15; x=x+1){
      // send write address
      digitalWrite (SSarray[x], LOW);
      SPI.transfer(0);
      for (y=0; y<8; y=y+1){
        Readarray[(x*15)+y] = SPI.transfer(0);
      } // next register
      digitalWrite(SSarray[x], HIGH);
    } // next chip

    // ****  end here ****
/*
    // send the data out, loop within a loop again

    for (x=0; x<15; x=x+1){
      Serial.print ("Device ");
      Serial.print (x);

      for (y=0; y<8; y=y+1){
        Serial.print (" R ");
        Serial.print (y);
        Serial.print (" ");
        Serial.print (Readarray[(x*15)+y]);
      } // next register
      Serial.println("");  // end line
    } // next chip

    // start another set of samples
    // send register address and value to start
    for (x=0; x<15; x=x+1){
      digitalWrite (SSarray[x], LOW);
      SPI.transfer(config_write);
      SPI.transfer(B10000100); // try B11100100 also
      // 100X010Xb From Table 3: Fault detection with automatic delay
      // D7, 1 = bias on
      // D6, 1 = conversions normally off
      // D5, 1 = start 1-shot conversion, conversion takes ~52mS
      // D4, 0 = 2-wire mode
      // D3, Fault Detection Cycle Control, use 0
      // D2, Fault Detection Cycle Control, use 1
      // D1, 0 = do not clear Fault register bits
      // D0, 0 = 60 Hz filter mode
      digitalWrite (SSarray[x], HIGH);
    } // end start sample loop
*/
  } // end time check
} // end loop

Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 54
Posts: 1848
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Gang,
Have a custom 1284P board with a bunch of temperature sensors accessed via SPI with individual SS lines.
IDE 1.0.3
Want to read them all every so many seconds & send data out.
When I comment out one section of code, it works great.
When it is, the time checking is totally hosed.
Any ideas?  This has me totally stumped.

Hosed time check results

time check 5000
time check 4294906767
time check 4294901592
time check 4294841247
time check 4294775716
time check 4294710190
time check 4294705011
time check 4294644667
time check 4294579136
time check 4294513609

Result seems to be going  backwards?!?

Code:
/* 
 Code to read 15 MAX31865 RTD chips via ATMega1284P & send data out via Serial port using FTDI chip.
 */

#include <SPI.h>

// declare chip selects
// 0, 1 are serial pins
byte ss0 = 2;
byte ss1 = 3;
byte ss2 = 4;
byte ss3 = 5;
byte ss4 = 6;
byte ss5 = 7;
byte ss6 = 8;
byte ss7 = 9;
byte ss8 = 10;
// 11, 12, 13 are SPI pins
byte ss9 = 14;
byte ss10 = 15;
byte ss11 = 16;
byte ss12 = 17;
byte ss13 = 18;
byte ss14 = 19;


byte SSarray[] = {
  2,3,4,5,6,7,8,9,10,14,15,16,17,18,19};

// 20-31 not used

//declare variables
// registers
byte config_read = 0x00;
byte config_write = 0x80;
byte RTD_MSBs = 0x01;
byte RTD_LSBs = 0x02;
byte High_Fault_Threshold_MSB_read = 0x03; // 83h FFh R/W
byte High_Fault_Threshold_MSB_write = 0x83;
byte High_Fault_Threshold_LSB_read = 0x04; // 84h FFh R/W
byte High_Fault_Threshold_LSB_write = 0x84;
byte Low_Fault_Threshold_MSB_read = 0x05; // 85h 00h R/
byte Low_Fault_Threshold_MSB_write = 0x85;
byte Low_Fault_Threshold_LSB_read = 0x06; // 86h 00h R/W
byte Low_Fault_Threshold_LSB_write = 0x86;
byte Fault_Status_read = 0x07; // 00h R

byte Readarray[120] ; // 8 x 15 RTDs, start on 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112

I would suggest using a doubly dimensioned array instead of doing the dimensioning yourself:

Code:
byte Readarray[16][8];

Code:
byte x; // counter
byte y; // counter

unsigned long currentTime;
unsigned long endTime;
unsigned long elapsedTime;
//unsigned long duration = 55; // conversion time, milliseconds
unsigned long duration = 5000UL; // Set longer for degug, keep PC serial port from getting swamped

void setup(){
  // set up output pins
  for (x=0; x<15; x=x+1){
    pinMode(SSarray[x], OUTPUT);
  }

  Serial.begin(115200);
  SPI.begin(); // default 4 MHz

I would suggest initializing endTime here for the initial time to check:

Code:
  endTime = mills () + duration;

Code:
} // end setup

void loop(){
  currentTime = millis();
  elapsedTime = currentTime - endTime;
  if ( elapsedTime >= duration){ // report on prior sample
    endTime = endTime + duration; // set for next time check
[/quote

This is where I suspect one bug is, and that is rather than incrementing endTime, you should be setting to to current time + the next duration:

Code:
    endTime = currentTime + duration;

Code:
    Serial.print ("time check ");
    Serial.println (elapsedTime);

    // ****  Time check works correctly if this section is commented out ****
    // loop within a loop - outer is a chip, inner is the 8 registers
    for (x = 0; x<15; x=x+1){
      // send write address
      digitalWrite (SSarray[x], LOW);
      SPI.transfer(0);
      for (y=0; y<8; y=y+1){
        Readarray[(x*15)+y] = SPI.transfer(0);

Here I would use:

Code:
      Readarray[x][y] = SPI.transfer(0);

Code:
      } // next register
      digitalWrite(SSarray[x], HIGH);
    } // next chip

    // ****  end here ****
/*
    // send the data out, loop within a loop again

    for (x=0; x<15; x=x+1){
      Serial.print ("Device ");
      Serial.print (x);

      for (y=0; y<8; y=y+1){
        Serial.print (" R ");
        Serial.print (y);
        Serial.print (" ");
        Serial.print (Readarray[(x*15)+y]);

And change this to:

Code:
      Serial.print (Readarray[x][y]);

Code:
      } // next register
      Serial.println("");  // end line
    } // next chip

    // start another set of samples
    // send register address and value to start
    for (x=0; x<15; x=x+1){
      digitalWrite (SSarray[x], LOW);
      SPI.transfer(config_write);
      SPI.transfer(B10000100); // try B11100100 also
      // 100X010Xb From Table 3: Fault detection with automatic delay
      // D7, 1 = bias on
      // D6, 1 = conversions normally off
      // D5, 1 = start 1-shot conversion, conversion takes ~52mS
      // D4, 0 = 2-wire mode
      // D3, Fault Detection Cycle Control, use 0
      // D2, Fault Detection Cycle Control, use 1
      // D1, 0 = do not clear Fault register bits
      // D0, 0 = 60 Hz filter mode
      digitalWrite (SSarray[x], HIGH);
    } // end start sample loop
*/
  } // end time check
} // end loop


Logged

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The logical side of my brain seems to be fuzzed up lately, from going in too many
small circles, but isn't the following value always negative? [if not, well, never mind].

elapsedTime = currentTime - endTime;
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The variable name 'endTime' seems misleading since it holds a start time, but otherwise the timing code looks correct.

The use of SSarray seems unsafe (since the size is hard-coded) but currently correct.

The use of Readarray seems unsafe and wrong; with x and y at maximum values of 14 and 7, you will be accessing index 217, but the array size is only 120. I suspect this is causing memory corruption and overwriting you timer variables.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 538
Posts: 27088
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, the arrays, I comfortable with it as is.

can't be negative, being unsigned long

I seem to be having a mental lapse as well, as I can't get this simple thing working!

15 * 8 = 120, how is it getting to 217?
I changed the array size to 240, and now its working as expected. I don't see where the growth is coming from.

Code:
/* 
 Code to read 15 MAX31865 RTD chips via ATMega1284P & send data out via Serial port using FTDI chip.
 */

#include <SPI.h>

// declare chip selects
// 0, 1 are serial pins
byte ss0 = 2;
byte ss1 = 3;
byte ss2 = 4;
byte ss3 = 5;
byte ss4 = 6;
byte ss5 = 7;
byte ss6 = 8;
byte ss7 = 9;
byte ss8 = 10;
// 11, 12, 13 are SPI pins
byte ss9 = 14;
byte ss10 = 15;
byte ss11 = 16;
byte ss12 = 17;
byte ss13 = 18;
byte ss14 = 19;


byte SSarray[] = {
  2,3,4,5,6,7,8,9,10,14,15,16,17,18,19};

// 20-31 not used

//declare variables
// registers
byte config_read = 0x00;
byte config_write = 0x80;
byte RTD_MSBs = 0x01;
byte RTD_LSBs = 0x02;
byte High_Fault_Threshold_MSB_read = 0x03; // 83h FFh R/W
byte High_Fault_Threshold_MSB_write = 0x83;
byte High_Fault_Threshold_LSB_read = 0x04; // 84h FFh R/W
byte High_Fault_Threshold_LSB_write = 0x84;
byte Low_Fault_Threshold_MSB_read = 0x05; // 85h 00h R/
byte Low_Fault_Threshold_MSB_write = 0x85;
byte Low_Fault_Threshold_LSB_read = 0x06; // 86h 00h R/W
byte Low_Fault_Threshold_LSB_write = 0x86;
byte Fault_Status_read = 0x07; // 00h R

byte Readarray[240] ; // 8 x 15 RTDs, start on 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112

byte x; // counter
byte y; // counter

unsigned long currentMillis;
unsigned long previousMillis;
unsigned long elapsedMillis;
//unsigned long duration = 55; // conversion time, milliseconds
unsigned long interval = 5000UL; // Set longer for degug, keep PC serial port from getting swamped

void setup(){
  // set up output pins
  for (x=0; x<15; x=x+1){
    pinMode(SSarray[x], OUTPUT);
  }

  Serial.begin(115200);
  SPI.begin(); // default 4 MHz

} // end setup

void loop(){
unsigned long  currentMillis = millis();
elapsedMillis = currentMillis - previousMillis;
  if ( elapsedMillis >= interval){ // report on prior sample
    previousMillis = currentMillis; // set for next time check
    Serial.print ("elapsedMillis ");
    Serial.println (elapsedMillis);

    // loop within a loop - outer is a chip, inner is the 8 registers
    for (x = 0; x<15; x=x+1){
      // send write address
      digitalWrite (SSarray[x], LOW);
      SPI.transfer(0);
      for (y=0; y<8; y=y+1){
        Readarray[(x*15)+y] = SPI.transfer(0);
      } // next register
      digitalWrite(SSarray[x], HIGH);
    } // next chip

    // send the data out, loop within a loop again

    for (x=0; x<15; x=x+1){
      Serial.print ("Device ");
      Serial.print (x);

      for (y=0; y<8; y=y+1){
        Serial.print (" R ");
        Serial.print (y);
        Serial.print (" ");
        Serial.print (Readarray[(x*15)+y]);
      } // next register
      Serial.println("");  // end line
    } // next chip

    // start another set of samples
    // send register address and value to start
    for (x=0; x<15; x=x+1){
      digitalWrite (SSarray[x], LOW);
      SPI.transfer(config_write);
      SPI.transfer(B10000100); // try B11100100 also
      // 100X010Xb From Table 3: Fault detection with automatic delay
      // D7, 1 = bias on
      // D6, 1 = conversions normally off
      // D5, 1 = start 1-shot conversion, conversion takes ~52mS
      // D4, 0 = 2-wire mode
      // D3, Fault Detection Cycle Control, use 0
      // D2, Fault Detection Cycle Control, use 1
      // D1, 0 = do not clear Fault register bits
      // D0, 0 = 60 Hz filter mode
      digitalWrite (SSarray[x], HIGH);
    } // end start sample loop

  } // end time check
} // end loop


Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

15 * 8 = 120, how is it getting to 217?

At line 55:

Code:
Readarray[(x*15)+y] = SPI.transfer(0);

The range of x is 0 .. 14. The range of y is 0 .. 7. The range of (x*15)+y is 0 .. 217.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 538
Posts: 27088
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah!  Did it in two places too. Thanks PeterH!

Got that fixed, time now elapsing as planned.

Now to break out the platinum RTDs and see if the MAX31865s are working ...
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

can't be negative, being unsigned long

May not have been your problem, however, the difference is shown at bottom.
Code:
unsigned long x1 = 10L;
unsigned long x2 = 20L;

void setup() {
  Serial.begin(57600);
}

void loop()
{
  Serial.println( (x1 - x2) );
  delay(1000);
}

printout = 4294967286
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 538
Posts: 27088
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Was not the problem. Writing to twice as much memory as was expected was the problem.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I thought that might have had something to do with your values, but in any case
you have it fixed.
Quote
time check 5000
time check 4294906767
time check 4294901592
time check 4294841247
time check 4294775716
Logged

Pages: [1]   Go Up
Jump to: