What does it mean when I can't upload my program?

Hi,
I can’t upload programs to Arduino without hitting the reset button. The arduino remains unresponsive until I hit the button and I can’t figure out why. In my program, I’m not touching the TX or RX ports. Anyone have any other ideas why the Arduino won’t upload?

In other codes I’ve written for the same project that are structurally similar, the Arduino remains responsive. I’ve looked at the scant differences and can’t work out what could be causing the problem.

The only theory I have is that, because I am using direct port manipulation, I am attempting to change the ports too quickly and that is causing some sort of hiccup? Anyone have any insight?

/* Multiplexing 43-segment LED display */

#include <math.h>

const int columnPins[] = {3, A0, A1, A2, A3, A4, A5};
const int rowPins[] = {13, 5, 6, 9, 10, 11, 12};

byte fadeUpD[64][7];
byte fadeUpC[64][7];
byte fadeUpB[64][7];

int randCounter;
int newCounter;
int newCounter2;

byte patternFadeB[64][7];
byte patternFadeC[64][7];
byte patternFadeD[64][7];


byte colSegD[7];
byte colSegF[7];

int randNumb;

int segmentArray[7][7];
int dimSegmentArray[7][7];
int randDesign[600];

void setup() {
    for (int i = 0; i < 7; i++)       //set pins as outputs
  { 
    pinMode(rowPins[i], OUTPUT);
    pinMode(columnPins[i], OUTPUT);
  }
  
  for (int i = 0; i < 7; i++) {
 for (int x = 0; x < 64; x++) {       //initialize row and column pin mapping
    fadeUpB[x][i] = B00000000; 
    fadeUpC[x][i] = B00000000;
    fadeUpD[x][i] = B00000000; 
  }
    colSegD[i] = B00000000;
    colSegF[i] = B00000000;
  }
  
                                    //set column port mapping
  colSegD[0] = B00000001;
  colSegF[1] = B10000000;
  colSegF[2] = B01000000;
  colSegF[3] = B00100000;
  colSegF[4] = B00010000;
  colSegF[5] = B00000010;
  colSegF[6] = B00000001;
  

  
pinMode(A7, INPUT);                 //set random seed pin as input
randomSeed(analogRead(A7));         //seed random number generator

//generate random design

for (int colCount = 0; colCount < 7; colCount++)
      {
        for (int rowCount = 0; rowCount < 7; rowCount++)
        {
          randNumb = random(0,20);
          if (randNumb == 1)   //for random(a,b), futz with value b to change the periodicity of new segments occurring
          {
            if (rowCount == 0)  {  //if segment is activated, program direct port map into fade up matrix
            fadeUpC[0][colCount] |= B10000000;
            patternFadeC[0][colCount] |= B10000000; //record what port to fade out in 64 cycles
            }
            if (rowCount == 1){
            fadeUpC[0][colCount] |= B01000000;
            patternFadeC[0][colCount] |= B01000000;
            }
            if (rowCount == 2) {
            fadeUpD[0][colCount] |= B10000000;
            patternFadeD[0][colCount] |= B10000000;
            }
            if (rowCount == 3) {
            fadeUpB[0][colCount] |= B00100000;
            patternFadeB[0][colCount] |= B00100000;
            }
            if (rowCount == 4) {
            fadeUpB[0][colCount] |= B01000000;
            patternFadeB[0][colCount] |= B01000000;
            }
            if (rowCount == 5) {
            fadeUpB[0][colCount] |= B10000000;
            patternFadeB[0][colCount] |= B10000000;
            
            if (rowCount == 6) {
            fadeUpD[0][colCount] |= B01000000;
            patternFadeD[0][colCount] |= B01000000;
            }
          }
        }
      }*/
      for (int x =0; x < 600; x++) {
      randDesign[x] = random(0,10);
      }
      randCounter = 0;
  }


//MAIN LOOP
void loop() {
for (int masterLoop = 1; masterLoop < 32000; masterLoop++)
{
  newCounter = masterLoop % 64;

//turn off segment that needs to fade
for (int x = 0; x < 7; x++)
      {
        fadeUpB[0][x] = fadeUpB[0][x] & (fadeUpB[0][x] ^ patternFadeB[newCounter][x]);
        fadeUpC[0][x] = fadeUpC[0][x] & (fadeUpC[0][x] ^ patternFadeC[newCounter][x]);
        fadeUpD[0][x] = fadeUpD[0][x] & (fadeUpD[0][x] ^ patternFadeD[newCounter][x]);
      }  
 
  
  
  
  //OUTPUT -----
  for (int level = 0; level < 64; level++)  //At each power level, the segment will be activated/deactivated.
  {
    for (int col = 0; col < 7; col++)
    {
      //T = 0 ON
      PORTF = colSegF[col];    //Turn on columns at T = 0.
      PORTD = colSegD[col] | fadeUpD[level][col];    //This will be all columns for the pattern.
      PORTB = fadeUpB[level][col];
      PORTC = fadeUpC[level][col];
      delayMicroseconds(10);
      
      PORTF = 0;
      PORTD = 0;
      PORTB = 0;
      PORTC = 0;
    }
  }
  //END OUTPUT----
  
  
  
  
  //shift segments
   for (int i = 63; i > 0; i--)
    {
      
      for (int x = 0; x < 7; x++)
      {
        fadeUpB[i][x] = fadeUpB[i-1][x];    //shift segments to next-longest illuminated slot
        fadeUpC[i][x] = fadeUpC[i-1][x];
        fadeUpD[i][x] = fadeUpD[i-1][x];
        //delay(10);
      }
  
  
//load in new design
  //convert design to port manipulation

    for (int colCount = 0; colCount < 7; colCount++)
    {
      for (int rowCount = 0; rowCount < 7; rowCount++)
      {
        randCounter++;
        if (randDesign[randCounter] == 1)   
        { 
          if (rowCount == 0)  {  //if segment is activated, program direct port map into fade up matrix
          fadeUpC[0][colCount] |= B10000000;
          patternFadeC[newCounter][colCount] |= B10000000; //record what port to fade out after 64 cycles
          }
          if (rowCount == 1){
          fadeUpC[0][colCount] |= B01000000;
          patternFadeC[newCounter][colCount] |= B01000000;
          }
          if (rowCount == 2) {
          fadeUpD[0][colCount] |= B10000000;
          patternFadeD[newCounter][colCount] |= B10000000;
          }
          if (rowCount == 3) {
          fadeUpB[0][colCount] |= B00100000;
          patternFadeB[newCounter][colCount] |= B00100000;
          }
          if (rowCount == 4) {
          fadeUpB[0][colCount] |= B01000000;
          patternFadeB[newCounter][colCount] |= B01000000;
          }
          if (rowCount == 5) {
          fadeUpB[0][colCount] |= B10000000;
          patternFadeB[newCounter][colCount] |= B10000000;
          }
          if (rowCount == 6) {
          fadeUpD[0][colCount] |= B01000000;
          patternFadeD[newCounter][colCount] |= B01000000;
          //delay(10);
          }
        }
      }
    }
    }
    newCounter2 = masterLoop % 64;
    
  } 
}

I'm inferring from what you say that the problem only arises after you upload the program you have posted. If you upload other programs you have no difficulty uploading subsequent programs. Is that correct?

What Arduino are you using?

I note that you have direct writes to PORTB, C, D and F without any regard for what other things might be using those ports. I haven't checked the datasheet but if the bootload process needs any pins in those ports you will be interfering with it. What PORT are pins 0 and 1 in?

...R

What Robin said.

PORTF = 0; PORTD = 0; PORTB = 0; PORTC = 0;

Doesn't sound too good to me!

Hi, this takes me way back with machine code and microchip. When using direct port writes, we were taught, you should get in the habit of using a bit mask to make sure that only the port pins you want to control are changed, any port pin that you do not want changed will remain unchanged. Just sending 10101000 and all you want to control are bits 7 to 3, will also change bits 2 to 0 to zero. Especially if 2 to 0 are actually inputs, you will have problems. Using a bit mask you can isolate the 2 to 0 bits and they will not be affected. Now I'd have to get my books back out to find out the method of application. (My old notes and books are filed under the biblical method, seek and ye shall find)

There has to be someone here who can bring us up to speed.

Tom...... :)

I use simple methods for that, examples: Clear a bit: PORTD = PORTD & 0b11011111; // clear bit 5, leave rest alone

Set a bit: PORTD = PORTD | 0b00100000; // set bit 5, leave rest alone

Toggle a bit: PIND = 0b00100000; // toggle bit 5, changes a low to high, and a high to low.

Hi, thankyou, CrossRoads, I haven’t had to do that in ages, too much industrial stuff.
Arduino brings you back down to basics which is good.

Thanks mate…
Tom… :slight_smile:

Thanks for responses—

Robin2:
If you upload other programs you have no difficulty uploading subsequent programs. Is that correct?

Yes that’s correct.

What Arduino are you using?

Micro.

I note that you have direct writes to PORTB, C, D and F without any regard for what other things might be using those ports. What PORT are pins 0 and 1 in?

thegoodhen:
What Robin said.

PORTF = 0;
PORTD = 0;
PORTB = 0;
PORTC = 0;

Doesn’t sound too good to me!

TX and RX are on ports D2 and D3. I’ll add a mask, but the problem is, I use this many times in the other code that works perfectly fine. Is it luck?

Here is a sample of the code that does successfully work.

/*
 Multiplexing with direct port mapping for Arduino Micro, with dimming for individual panels
 */

//BEGIN MAIN LOOP---------
void loop() 
{    
  for (int loopDeloop = 0; loopDeloop < 32000; loopDeloop++)
  {
  for (int counter = 16; counter < fadeTime*2; counter++)
  {
      
  //FADE CODE
    
      for (int colCount = 0; colCount < 7; colCount++)
      {
      //Fade out Segments
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(counter/2);

     
      PORTF = colSegF[colCount];
      PORTD = rowSegD[colCount] | colSegD[colCount];
      PORTB = rowSegB[colCount];
      PORTC = rowSegC[colCount];
      delayMicroseconds((fadeTime-(counter/2)));
      
      //fade in dim segments
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds((fadeTime-(counter/2)));
     
   
      PORTF = colSegF[colCount];
      PORTD = dimrowSegD[colCount] | colSegD[colCount];
      PORTB = dimrowSegB[colCount];
      PORTC = dimrowSegC[colCount];
      delayMicroseconds(counter/2);
      
      //constant on old segs
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime);

      // on column
      PORTF = colSegF[colCount];
      PORTD = oldrowSegD[colCount] | colSegD[colCount];
      PORTB = oldrowSegB[colCount];
      PORTC = oldrowSegC[colCount];
      delayMicroseconds(fadeTime);
      }
  }
      
     //constant on
     
      /*for (int colCount = 0; colCount < 7; colCount++)
      {
           
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime);
      //turn on old
      PORTF = colSegF[colCount];
      PORTD = dimrowSegD[colCount] | colSegD[colCount];
      PORTB = dimrowSegB[colCount];
      PORTC = dimrowSegC[colCount];
      delayMicroseconds(fadeTime);
      
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime);
      //turn on old
      PORTF = colSegF[colCount];
      PORTD = oldrowSegD[colCount] | colSegD[colCount];
      PORTB = oldrowSegB[colCount];
      PORTC = oldrowSegC[colCount];
      delayMicroseconds(fadeTime-10);
      //copy old design
      rowSegB[colCount] = oldrowSegB[colCount];
      rowSegC[colCount] = oldrowSegC[colCount];
      rowSegD[colCount] = oldrowSegD[colCount];
      }*/
     
    
    //CONSTANT CODE
    
    for (int counternew = 0; counternew < 400; counternew++)
    {
      for (int colCount = 0; colCount < 7; colCount++)
      {
        freqIncrement = -freqIncrement;
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime+freqIncrement);
      //turn on old
      PORTF = colSegF[colCount];
      PORTD = dimrowSegD[colCount] | colSegD[colCount];
      PORTB = dimrowSegB[colCount];
      PORTC = dimrowSegC[colCount];
      delayMicroseconds(fadeTime-freqIncrement);
      
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime+freqIncrement);
      //turn on old
      PORTF = colSegF[colCount];
      PORTD = oldrowSegD[colCount] | colSegD[colCount];
      PORTB = oldrowSegB[colCount];
      PORTC = oldrowSegC[colCount];
      delayMicroseconds(fadeTime-7-freqIncrement);
      //copy old design
      rowSegB[colCount] = oldrowSegB[colCount];
      rowSegC[colCount] = oldrowSegC[colCount];
      rowSegD[colCount] = oldrowSegD[colCount];
      }
     
    }
//CONSTANT CODE 2

      for (int colCount = 0; colCount < 7; colCount++)
      {
        freqIncrement = -freqIncrement;
           //Turn off column
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime-freqIncrement);
      //turn on old
      PORTF = colSegF[colCount];
      PORTD = dimrowSegD[colCount] | colSegD[colCount];
      PORTB = dimrowSegB[colCount];
      PORTC = dimrowSegC[colCount];
      delayMicroseconds(fadeTime+freqIncrement);
      
      PORTF =0;
      PORTD =0;
      PORTB =0;
      PORTC =0;
      delayMicroseconds(fadeTime-freqIncrement);
      //turn on 
      PORTF = colSegF[colCount];
      PORTD = rowSegD[colCount] | colSegD[colCount];
      PORTB = rowSegB[colCount];
      PORTC = rowSegC[colCount];
      delayMicroseconds(fadeTime-7+freqIncrement);
      //copy old design
      oldrowSegB[colCount] = dimrowSegB[colCount];
      oldrowSegC[colCount] = dimrowSegC[colCount];
      oldrowSegD[colCount] = dimrowSegD[colCount];
            //Turn off column
      }
    
       //CONSTANT 3: generate new design
       
       for (int rowCount = 0; rowCount < 7; rowCount++)
       {
         for (int colCount = 0; colCount < 7; colCount++)
         {
           freqIncrement = -freqIncrement;
          PORTF =0;
          PORTD =0;
          PORTB =0;
          PORTC =0;
          delayMicroseconds(fadeTime-10-freqIncrement);
          //turn on old
          PORTF = colSegF[colCount];
          PORTD = oldrowSegD[colCount] | colSegD[colCount];
          PORTB = oldrowSegB[colCount];
          PORTC = oldrowSegC[colCount];
          delayMicroseconds(fadeTime-140+freqIncrement);
          
          randNumb = random(0, 20); // tune this to change average number of tiles (a,b) where a = 0 and b = higher, less tiles. takes 130 us to process.
          
          PORTF =0;
          PORTD =0;
          PORTB =0;
          PORTC =0;
          delayMicroseconds(fadeTime-10-freqIncrement);
          //turn on old
          PORTF = colSegF[colCount];
          PORTD = rowSegD[colCount] | colSegD[colCount];
          PORTB = rowSegB[colCount];
          PORTC = rowSegC[colCount];
          delayMicroseconds(fadeTime-23+freqIncrement);  //tune this value to reduce flicker at end of cycle
          
      
  
         
          //make new design
          if (randNumb == 1)
          {
            if (rowCount == 0)
            dimrowSegC[colCount] = B10000000;
            if (rowCount == 1)
            dimrowSegC[colCount] = B01000000;
            if (rowCount == 2)
            dimrowSegD[colCount] = B10000000;
            if (rowCount == 3)
            dimrowSegB[colCount] = B00100000;
            if (rowCount == 4)
            dimrowSegB[colCount] = B01000000;
            if (rowCount == 5)
            dimrowSegB[colCount] = B10000000;
            if (rowCount == 6)
            dimrowSegD[colCount] = B01000000;
          }
          else
          {
            if (rowCount == 0)
            dimrowSegC[colCount] = dimrowSegC[colCount];
            if (rowCount == 1)
            dimrowSegC[colCount] = dimrowSegC[colCount];
            if (rowCount == 2)
            dimrowSegD[colCount] = dimrowSegD[colCount];
            if (rowCount == 3)
            dimrowSegB[colCount] = dimrowSegB[colCount];
            if (rowCount == 4)
            dimrowSegB[colCount] = dimrowSegB[colCount];
            if (rowCount == 5)
            dimrowSegB[colCount] = dimrowSegB[colCount];
            if (rowCount == 6)
            dimrowSegD[colCount] = dimrowSegD[colCount];
           }
         }
       }
  }
}

I think I have figured it out!

byte fadeUpD[64][7];
byte fadeUpC[64][7];
byte fadeUpB[64][7];

int randCounter;
int newCounter;
int newCounter2 = 0;

byte patternFadeB[65][7];
byte patternFadeC[65][7];
byte patternFadeD[65][7];

As you can see I am declaring three 2D arrays of 64 by 7, and three more of 65 by 7. That’s 2709 bytes which I think is overflowing the RAM. The problem is, I need to use these arrays in the program, is there another option for me? I can’t use PROGMEM because flash can’t be changed while the program is running.

You haven't posted your code so I have no idea how those arrays are used or whether there might be a more economical way to do what you want.

Perhaps the full arrays can be in Progmem and have a working single row that can be changed?

...R

Robin, here’s my new code. I’ve eliminated the set of large arrays. However I’m encountering a different issue now. It seems that whenever I try to upload new code, the arduino simply restarts the existing program and no upload takes place, even though the arduino program says upload complete.

#include <avr/io.h>
#include <avr/pgmspace.h>

const int columnPins[] = {3, A0, A1, A2, A3, A4, A5};
const int rowPins[] = {13, 5, 6, 9, 10, 11, 12};

int randCounter;
int randDesign[600];
int newCounter;
int newCounter2;
int randNumb;

byte colSegD[7];
byte colSegF[7];

byte fadeUpD[100][7];
byte fadeUpC[100][7];
byte fadeUpB[100][7];

byte newPatternD[7];
byte newPatternC[7];
byte newPatternB[7];

void setup() {
  Serial.begin(9600);
 // while (! Serial);
  pinMode(A8, INPUT);                 //set random seed pin as input
randomSeed(analogRead(A8)); 
Serial.print(analogRead(A8));
  // put your setup code here, to run once:
for (int i = 0; i < 7; i++)       //set pins as outputs
  { 
    pinMode(rowPins[i], OUTPUT);
    pinMode(columnPins[i], OUTPUT);
  }
  
  colSegD[0] = B00000001;
  colSegF[1] = B10000000;
  colSegF[2] = B01000000;
  colSegF[3] = B00100000;
  colSegF[4] = B00010000;
  colSegF[5] = B00000010;
  colSegF[6] = B00000001;
  
  for (int colCount = 0; colCount < 7; colCount++)
      {
        for (int rowCount = 0; rowCount < 7; rowCount++)
        {
          randNumb = random() % 10;
          if (randNumb == 1)   //for random(a,b), futz with value b to change the periodicity of new segments occurring
          {
            if (rowCount == 0)  {  //if segment is activated, program direct port map into fade up matrix
            fadeUpC[0][colCount] |= B10000000;
            
            }
            if (rowCount == 1) {
            fadeUpC[0][colCount] |= B01000000;
            
            }
            if (rowCount == 2) {
            fadeUpD[0][colCount] |= B10000000;
            
            }
            if (rowCount == 3) {
            fadeUpB[0][colCount] |= B00100000;
            
            }
            if (rowCount == 4) {
            fadeUpB[0][colCount] |= B01000000;
            
            }
            if (rowCount == 5) {
            fadeUpB[0][colCount] |= B10000000;
            
            }
            if (rowCount == 6) {
            fadeUpD[0][colCount] |= B01000000;
            
            }
          }
        }
      }
}

void loop() {
for (int masterLoop = 1; masterLoop < 32000; masterLoop++) {
  newCounter = masterLoop % 100;
  
  //flip a bit
  for (int col =0; col < 7; col++) {
  fadeUpB[0][col] = fadeUpB[0][col] ^ newPatternB[col];
  fadeUpC[0][col] = fadeUpC[0][col] ^ newPatternC[col];
  fadeUpD[0][col] = fadeUpD[0][col] ^ newPatternD[col];
  }
  
  for (int level = 0; level < 100; level++)  //At each power level, the segment will be activated/deactivated.
  {
    for (int col = 0; col < 7; col++)
    {
      
      PORTF = B00000000;
      PORTD &= B00001100;
      PORTB = B00000000;
      PORTC = B00000000;

      //delay(100);
      //T = 0 ON
      PORTF = colSegF[col];          //Turn on columns at T = 0.
      PORTD = (fadeUpD[level][col] | colSegD[col]);   //This will be all columns for the pattern.
      PORTB = fadeUpB[level][col];
      PORTC = fadeUpC[level][col];
      //delay(100);
      delayMicroseconds(8);
    }
  }
  
  //every other cycle, shift levels up and generate new pattern
  for (int i = 63; i > 0; i--)      //shift segments to next-longest illuminated slot
    {
      for (int x = 0; x < 7; x++)
      {
        fadeUpB[i][x] = fadeUpB[i-1][x];    
        fadeUpC[i][x] = fadeUpC[i-1][x];
        fadeUpD[i][x] = fadeUpD[i-1][x];
        
        //delay(10);
      }
    }
    for (int x = 0; x < 7; x++)
    {
      newPatternB[x] = 0;
      newPatternC[x] = 0;
      newPatternD[x] = 0;
    }
    for (int colCount = 0; colCount < 7; colCount++)
      {
        for (int rowCount = 0; rowCount < 7; rowCount++)
        {
          randNumb = random(0, 50);
          if (randNumb == 1)   //for random(a,b), futz with value b to change the periodicity of new segments occurring
          {
            if (rowCount == 0)  {  //if segment is activated, program direct port map into fade up matrix
            newPatternC[colCount] |= B10000000;
            
            }
            if (rowCount == 1) {
            newPatternC[colCount] |= B01000000;
            
            }
            if (rowCount == 2) {
            newPatternD[colCount] |= B10000000;
            
            }
            if (rowCount == 3) {
            newPatternB[colCount] |= B00100000;
            
            }
            if (rowCount == 4) {
            newPatternB[colCount] |= B01000000;
            
            }
            if (rowCount == 5) {
            newPatternB[colCount] |= B10000000;
            
            }
            if (rowCount == 6) {
            newPatternD[colCount] |= B01000000;
            
            }
          }
        }
      }
  
}
    
}

bwinter88: whenever I try to upload new code, the arduino simply restarts the existing program and no upload takes place, even though the arduino program says upload complete.

That would be pretty bizarre. I suggest you try uploading a standard blink sketch to confirm that uploading works. Make sure you select the correct serial port and board type before uploading.

You still seem to be dumping stuff into the Pin registers without regard for what might be there already and needed by something else.

You might try putting a 15sec delay at the top of setup() so when your program restarts it waits long enough for other things to happen.

If that works then I would assume the way you are using the Pin registers is causing the problem.

...R

I try to compile your new code and this is what get

Sketch uses 7,120 bytes (24%) of program storage space. Maximum is 28,672 bytes. Global variables use 2,324 bytes (90%) of dynamic memory, leaving 236 bytes for local variables. Maximum is 2,560 bytes. Low memory available, stability problems may occur

and you have few more local variables, this may be the problem.

int randDesign[600]; << 1200 bytes
byte fadeUpD[100][7];
byte fadeUpC[100][7];
byte fadeUpB[100][7];

Isn’t this 3300 bytes?
As noted, max SRAM is 2560.
Won’t stop upload, but will create performance errors.

Looking at the 32U4 datasheet, I don’t see how writing to the ports has any impact on loading code thru the USB interface.

If you select File:Preferences, enable Verbose outputs, what does it show when the upload is done?

CrossRoads:

int randDesign[600]; << 1200 bytes

byte fadeUpD[100][7];
byte fadeUpC[100][7];
byte fadeUpB[100][7];



Isn't this 3300 bytes?
As noted, max SRAM is 2560.
Won't stop upload, but will create performance errors.

Looking at the 32U4 datasheet, I don't see how writing to the ports has any impact on loading code thru the USB interface.

If you select File:Preferences, enable Verbose outputs, what does it show when the upload is done?

You’re right. I decreased the size and number of variables and it works fine now.