Uploading sketch works, but loop not executing

hi there,

I know this is not strictly related to the topic of this sub, but I think this might be the best place to ask this question anyways.

I have this sketch that is reading the colour input of 24 APDS9960 sensors via 4 multiplexers:

/**/

#include<Wire.h>
#include "Adafruit_APDS9960.h" /*include libraries*/

/***********************************************************************************************************************************************************************************************************************************************************/

// declarations

Adafruit_APDS9960 apds[1]; /*initialize sensor*/

byte tcaI2CAddress[] = {0x70, 0x71, 0x72, 0x73}; /*define array containing all the addresses*/
byte numberOfTCAs = 4; /* define number of TCAs used */
byte numberOfDevicesPerTCA = 6; /* define number of Sensors per TCA */
const int numberOfDevices = 24; /* define number of total devices */

/***********************************************************************************************************************************************************************************************************************************************************/

void setup() {
  Wire.begin();
  Serial.begin(115200); /*begin serial communication (Arduino -> PC) at 115200 Baud rate*/

  // 0. run i2c scanner
  Serial.println("I2C Scanner ready!");
  Serial.println();
  scanI2C(400000); /*run i2c scanner function*/
  Serial.println("-------------------------------");
  Serial.println();

  // 1. switch off all TCAs to make sure no two TCAs are active at the same time
  for (int i = 0; i < numberOfTCAs; i++){
  // Wire.beginTransmission(tcaI2CAddress[i]);
  // Wire.write(0);
  // Wire.endTransmission(); 
  closeTCA(i);
  }

  // 2. initialize sensors
  for (int i = 0; i < numberOfDevices; i++){

    byte tca = setTCAAndChannel(i);

    Serial.print("Initializing APDS_");
    Serial.println(i);
    Serial.println();
    
  if(!apds[i].begin()){ /*if function returns 0, print "failed to initialize...", else print "initialized!"*/
    Serial.println("failed to initialize device! Please check your wiring.");
    Serial.println();
  }
  else {Serial.println("Device initialized!");
  Serial.println();
  }
  
  apds[i].enableColor(true); /*enable color sensing mode*/

  // 3. close TCA
  closeTCA(tca);
  }
  
}

void loop() { 

  // 1. switch off all TCAs to make sure no two TCAs are active at the same time
  for (int i = 0; i < numberOfTCAs; i++){
  // Wire.beginTransmission(tcaI2CAddress[i]);
  // Wire.write(0);
  // Wire.endTransmission(); 
  closeTCA(i);
  }

  // 2. run color readings
  for (int i = 0; i < numberOfDevices; i++){

  byte tca = setTCAAndChannel(i);
    
  uint16_t r, g, b, c; /*create some variables to store the color data in*/

  while(!apds[i].colorDataReady()){ /*wait for color data to be ready*/
    delay(1); /*Adafruit example: 5ms; THIS DELAY ALONE WOULD AMOUNT TO 125 ms !!!!!*/
  }

  apds[i].getColorData(&r, &g, &b, &c); /*get the data and print the different channels*/

  int cl = map(c, 0 , 4097, 0, 255); /*map values 0-4097 to 0-255 to send less data (and because sensor outputs 0-4097 instead of 0-4096, so it's not possible to divide by 16 - maybe better to just clip?*/
  Serial.print(i);
  Serial.print(" ");
  Serial.println(cl);

  // 3. close TCA
  closeTCA(tca);
  }
  // Serial.println("****************************");  
  delay(1);
}

/**************************************************************************************************************************************************************************************************************************************************************/

byte setTCAAndChannel(byte i){ /* define function for setting TCA and sensor */
  byte tca = i/numberOfDevicesPerTCA; /* divide i (total # of devices) by # of TCAs, that way because it's int, 1,5 will still be 1, thereby selecting the correct TCA */
  byte channel = i%numberOfDevicesPerTCA; /* modulo... divide i (the total number of devices) by the # of devices per TCA and give the rest, e.g. 2%4 = 0*/

  Wire.beginTransmission(tcaI2CAddress[tca]);
  Wire.write(1 << channel);
  Wire.endTransmission(); 
   
  return tca; 
}

void closeTCA(byte tca){
  Wire.beginTransmission(tcaI2CAddress[tca]);
  Wire.write(0);
  Wire.endTransmission(); 
  }
  
void scanI2C(long frequency){
  
  String normal = "standard mode (100 kHz):";
  String fast = "fast mode (400 kHz):";
  String defaultStr = " !!!!! Invalid Frequency !!!!!";
  
  bool error = true;
  bool addressFound = false;
  
  Serial.print("Scanning in ");
  switch(frequency){ /* switch...case is similar to an if...then statement */
    case 100000:
      Serial.println(normal); /*print string "standard mode (100kHz)", previously defined as 'normal'*/
      break;
    case 400000:
      Serial.println(fast); /*print string "fast mode (400kHz)", previously defined as 'fast'*/
      break; /*ends the switch...case statement*/
  }
  
  Wire.setClock(frequency);
  for(int i=1; i<128; i++){
    Wire.beginTransmission(i); /*begins transmission on the specified address i, e.g. 127*/
    error = Wire.endTransmission(); /*Wire.endTransmission() returns bytes for status of transmission: 0 = success, 1 = data too long, ... 4 = other ; here "error" is set to 0 or "false" if Wire.endTransmission() returns 0 (= transmssion successful) and "true" for everything else (1 - 4)*/
    if(error == 0){ /*if the "error" Boolean is set to "false" (meaning the transmission was successful), proceed by ... */
      addressFound = true; /*setting "addressFound" to true*/
      Serial.print("0x"); /*prints the address of the i2c device from two components, first "0x" ... */
      Serial.println(i,HEX); /* ... and second the number where a device was found as HEX, i.e. 127 = 7F, totalling 0x7F*/
    }
  }
  if(!addressFound){ /*if no address was found for all 128 addresses, print: */
    Serial.println("No address recognized");
  }
  Serial.println();
}

I've tested it on a breadboard with all 24 sensors, the complete layout, on an Arduino Nano Every, and it works exactly as intended. I had absolutely no quarrels with it.

Now I've begun soldering my circuit and tested it with four muxers and one sensor each for starters, but for some reason, the loop doesn't execute and I'm not receiving any error messages either. It's simply not working. and interrupting in the middle of the setup sequence.

Has anyone ever experienced something similar? I've checked all the wires and they are soldered correctly. Any pointers what could be wrong here? A cold solder? anything?

I'm attaching a screenshot to show what the interrupted setup sequence looks like. the error message showed up also when the sketch did work during the breadboard trials that I did, I think it's related to the ATmega328 emulator on the Nano Every, so I don't think it's relevant here.

thanks, and best

I should maybe add that when I run the i2c scanner only, it works correctly about 1/5 times upon reset, and 4/5 it's the same as for my original sketch. I really don't understand what's going on.

this is the sketch:

/*This sketch runs the i2c scanner and is able to discover all four muxers.*/

/*NEXT: ALL MUXERS, 1 color sensor each*/

#include<Wire.h>
#define TCA9548A_I2C_ADDRESS  0x73
#define TCA9548A_CHANNEL_0    0

void setup() {
  Wire.begin();
  Serial.begin(115200); /*begin serial communication (Arduino -> PC) at 115200 Baud rate*/
  Serial.println("I2C Scanner ready.");
  Serial.println();
  
  setTCAChannel(TCA9548A_CHANNEL_0); /*call function setTCAChannel in order to set the channel on the TCA (see below)*/
}

void loop() { 
  scanI2C(400000);
  Serial.println("****************************");
  Serial.println();
  delay(3000);
}


/*"Da bei jedem Takt ein Bit übertragen wird, entspricht die Taktrate der Datenrate in Bit/s*/
/******************************************/

void setTCAChannel(byte i){
  Wire.beginTransmission(TCA9548A_I2C_ADDRESS); /*write to sensor I2C address*/
  Wire.write(1 << i); /*queue for writing: shifts the variable "1" leftward by the number given by "i" (0-7): the result is 00000001, 00000010, etc. = the address on the muxer */
  Wire.endTransmission();  /*write to address and end transmission*/
}

/*******************************************/

void scanI2C(long frequency){
  
  String normal = "standard mode (100 kHz):";
  String fast = "fast mode (400 kHz):";
  String defaultStr = "Invalid Frequency";
  
  bool error = true;
  bool addressFound = false;
  
  Serial.print("Scanning in ");
  switch(frequency){ /* switch...case is similar to an if...then statement */
    case 100000:
      Serial.println(normal); /*print string "standard mode (100kHz)", previously defined as 'normal'*/
      break;
    case 400000:
      Serial.println(fast); /*print string "fast mode (400kHz)", previously defined as 'fast'*/
      break; /*ends the switch...case statement*/
  }
  
  Wire.setClock(frequency);
  for(int i=1; i<128; i++){
    Wire.beginTransmission(i); /*begins transmission on the specified address i, e.g. 127*/
    error = Wire.endTransmission(); /*Wire.endTransmission() returns bytes for status of transmission: 0 = success, 1 = data too long, ... 4 = other ; here "error" is set to 0 or "false" if Wire.endTransmission() returns 0 (= transmssion successful) and "true" for everything else (1 - 4)*/
    if(error == 0){ /*if the "error" Boolean is set to "false" (meaning the transmission was successful), proceed by ... */
      addressFound = true; /*setting "addressFound" to true*/
      Serial.print("0x"); /*prints the address of the i2c device from two components, first "0x" ... */
      Serial.println(i,HEX); /* ... and second the number where a device was found as HEX, i.e. 127 = 7F, totalling 0x7F*/
    }
  }
  if(!addressFound){ /*if no address was found for all 128 addresses, print: */
    Serial.println("No address recognized");
  }
  Serial.println();
}

If you can upload code, it's not related to Avrdude, stk500 or Bootloader issues :wink: Hence your topic has been moved to a more suitable location on the forum.

ok, sorry! :stuck_out_tongue:

How do you know this? Put more Serial.print statements in the loop and in the functions to determine where things don't go as expected.

What is a TCA? (Old pilots recognize this as a Terminal Control Area, but now known as Class-C).

How long are the wires to the sensor (total)? I2C is designed for short distances and once you get past a few feet, you are in experimental territory.

hi Steve, thanks for getting back about this!

ah yeah, didn't think of that. used to do it in the first breadboard-run but since it worked before I didn't think of doing it a second time. will do right away.

that's the multiplexer, TCA9548A.

between 20 and 70 cm (~24inches)

And they are all bundled in a group, or in a single cable, are they not?

And? Did you find your problem?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.