Atmega on stripboard needs reset to work.

Hi, I have a atmega168 bootloaded to run on its internal 8MHz clock. It's on some stripboard now, though it was previously on a breadboard and had the exact same problem. (A problem I've had with another project as well and still can't figure out).

The atmega168 is connected over the SPI bus to a nRF24L01+, and also a flash memory chip that operates over SPI. I have tied the reset pin high with a 10k resistor. The board is also connect to some leds that it makes flash. It's supposed to be a datalogging wireless energy monitor for my parents. :slight_smile: Now, when I power it on nothing happens unless I ground the reset pin and then release it (sending it back to 3.3v)...in which case all my code works fine.

I've got everything else to work great...I just can't seem to get it to work when it's turned on unless I manually reset it after...

I can post pictures if that would help?

Thanks in advance!

Deeksie

No idea what the problem is, but if you can reproduce it on a breadboard then is it possible to cure the problem by disconnecting any of the external hardware? If so, knowing which interface is causing it might give you a clue as to the nature of the problem.

Good idea. I've had a look, and I think it's the LED's I'm driving. It's actually a PCB with 4x1watt LED's on; RGBY. It uses buck drivers, so lots of inductors etc. The LED pcb has RGBY GND and V pinouts. So I draw 9v off the LED board, and use a 3.3v lin reg to get the power for the atmega, nRF24L01+ and flash chip. I can then use the atmega to PWM the RGBY pins. It all works great if I reset the board manually!

It's quite frustrating that I'm so close to having it work. I wish I had an oscilloscope so I could better analyse what's going on.

I might try putting some more caps on the power supply... any other ideas?

Cheers!

I take it back...just tried powering the board from my Arduino and using a 5mm led on the Green pin...it still needs a manual reset to work. :-/

EDIT: Just tried it with a 4700uF capacitor over Vin and GND...I don't think it's a power fluctuation problem.
Last time I had this problem was with the same circuit without the flash chip. As I have found the LED board is not the problem it seems the nRF24L01+ may be...

I have written my own code for the wireless chip (and the flash), instead of using the Mirf or RF24 libraries. I thought perhaps the SPI data was being garbled for the first moment it was switched on, but I place a 1 second delay at the top of setup(), before I set up the registers, and it still doesn't work without a reset.

Deeksie

Just had another go at sorting out the reset problem. This time I powered the nRF24L01+ off the A5 pin, thinking that I could turn it off and then on again to reset the wireless chip, in case that helped. Alas, it didn't work, so I reconnected the Vin pin to 3.3v, and put a 22uF cap over GND and Vin...that didn't help either.

The LED board I'm using needs to be driven low to turn off the LEDs. There are no pauses at the start of my program, but I have noticed that when I connect my unit to power, the LEDs flash very briefly. But that when I reset it, the LEDs stay on for much longer, close to 1/2 a second I would say. I know that the Arduino is supposed to pause on "start-up"...presumably that pause is indicated by the time the LEDs stay on.

Is it possible that when I plug the unit in the bootloader isn't loading properly, but that when I reset it it does? I know that it's supposed to pause before running code to see if it is about to be programmed...yes? And it only seems to do this when reset, not when plugged in.

I'm really struggling to find an answer!

I don't think my code will be of any help...but here it is:

#include <EEPROM.h>
#include <SPI.h>

#define CE 8
#define CSN 7
#define CSNm 6

#define GREEN 9
#define RED 3

int Direction = 1;
byte Data[32];
byte Storage[8];
byte PreviousState = 0;
byte eepromPosition = 0;
float FadeLevel = 0;
float LightPosition = 0;

unsigned int Import;
unsigned int Export;
unsigned int MemPlace;
unsigned long ImportTotal = 0;
unsigned long ExportTotal = 0;

unsigned long time;
unsigned long writeDatatime;

void setup()
{   
  Serial.begin(115200);
  
  pinMode(CE, OUTPUT);
  pinMode(CSN, OUTPUT);
  pinMode(CSNm, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(RED, OUTPUT);
  
  digitalWrite(CE, HIGH); // Set low for Tx
  digitalWrite(CSN, HIGH);
  digitalWrite(CSNm, HIGH);
  
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  
  SetupRegisters();
  setAddress(100); // Address to send data on
  
  setMemPlaceAndData(0);
  
  Serial.println("Starting...");
  
  time = millis();
  writeDatatime = millis()+60000;
}

void loop()
{ 
  time += 25;
  
  exportData();
  
  if(readData() == 1)
  {
     Import = unpackage(0)/12.5;
     Export = unpackage(4)/12.5; 
  }
  ImportTotal += Import;
  ExportTotal += Export;
  
  setLight(Import, Export);
  
  if(writeDatatime < millis())
  {
    writeDatatime += 60000;
    ImportTotal /= 2400;
    ExportTotal /= 2400;
    if(MemPlace < 65535)
    {
      packageData(ImportTotal, ExportTotal, 0, 0);
      writeData(MemPlace*8);
      EEPROM.write(eepromPosition*2, MemPlace & 0xFF);
      EEPROM.write((eepromPosition*2)+1, MemPlace >> 8);
      eepromPosition++;
      MemPlace++;
    }
    ImportTotal = 0;
    ExportTotal = 0;
  }
    
  while(time > millis())
  {
    delayMicroseconds(1);
  }
}

//#################### Memory Functions ####################
void setMemPlaceAndData(byte flag)
{
  unsigned int value = 0;
  unsigned int value2;
  
  if(flag == 1)
  {
    chipErase();
    while(readStatus() & 0x01)
    {
      delay(10);
    }
    
    for(int i=0; i<512; i++)
    {
      EEPROM.write(i,byte(0x00));
    }
    MemPlace = 1;
  }
  else
  {
    for(int i=0; i<256; i++)
    {
      value2 = EEPROM.read(i*2) + (long(EEPROM.read((i*2)+1) << 8));
      
      if(value < value2)
      {
        value = value2;
      }
    }
    MemPlace = value + 1;
  }
}

void exportData()
{
  if(Serial.available() > 0)
  {
    if(Serial.peek() == 'E')
    {
      sendTheData();
    }
    
    if(Serial.peek() == 'C')
    {
      setMemPlaceAndData(1);
    }
    
    Serial.read();
  }
}

void sendTheData() // NEED TO MODIFY FOR PROCESSING
{
  unsigned int place = MemPlace;
  
  while(place > 1)
  {
    readData((place-1)*8);
    for(int i=0; i<8; i += 2)
    {
      Serial.print(Storage[i]+(long(Storage[i+1]) << 8));
      Serial.print(",");
    }
    Serial.println();
    place--;
  }
}

void packageData(unsigned int imports, unsigned int exports, unsigned int powergen, unsigned int powerused)
{
  for(int i=0; i<2; i++)
  {
    Storage[i] = imports & 0xFF;
    imports = imports >> 8;
  }
  for(int i=2; i<4; i++)
  {
    Storage[i] = exports & 0xFF;
    exports = exports >> 8;
  }
  for(int i=4; i<6; i++)
  {
    Storage[i] = powergen & 0xFF;
    powergen = powergen >> 8;
  }
  for(int i=6; i<8; i++)
  {
    Storage[i] = powerused & 0xFF;
    powerused = powerused >> 8;
  }
}

byte readStatus()
{
  byte value;
  
  digitalWrite(CSNm, LOW);
  SPI.transfer(0x05);
  value = SPI.transfer(0x00);
  digitalWrite(CSNm, HIGH);
  
  return value;
}

void readData(long Address)
{
  byte AddressArray[3];
  
  for(int i=2; i>-1; i--)
  {
    AddressArray[i] = Address & 0xFF;
    Address = Address >> 8;
  }
  
  digitalWrite(CSNm, LOW);
  SPI.transfer(0x03);
  for(int i=0; i<3; i++)
  {
    SPI.transfer(AddressArray[i]);
  }
  
  for(int i=0; i<8; i++)
  {
    Storage[i] = SPI.transfer(0x00);
  }
  
  digitalWrite(CSNm, HIGH);
}

void writeData(long Address)
{
  writeEnable();
  
  byte AddressArray[3];
  
  for(int i=2; i>-1; i--)
  {
    AddressArray[i] = Address & 0xFF;
    Address = Address >> 8;
  }
  
  digitalWrite(CSNm, LOW);
  SPI.transfer(0x02);
  for(int i=0; i<3; i++)
  {
    SPI.transfer(AddressArray[i]);
  }
  
  for(int i=0; i<8; i++)
  {
    SPI.transfer(Storage[i]);
  }
  digitalWrite(CSNm, HIGH);
}

void chipErase()
{
  writeEnable();
  
  digitalWrite(CSNm, LOW);
  SPI.transfer(0xC7);
  digitalWrite(CSNm, HIGH);
  
  while(readStatus() & 0x01)
  {
    delayMicroseconds(10);
  }
} 

void writeEnable()
{
  digitalWrite(CSNm, LOW);
  SPI.transfer(0x06);
  digitalWrite(CSNm, HIGH);
}

//#################### Light Functions ####################
void setLight(unsigned int imports, unsigned int exports)
{
  byte pin;
  float rate;
  byte Level;
  if(imports > exports)
  {
    pin = RED;
    rate = imports;
  }
  else
  {
    pin = GREEN;
    rate = exports;
  }
  
  if(pin != PreviousState)
  {
    FadeLevel = 0.9;
  }
  
  rate /= 234.4;
  if((LightPosition + rate*Direction)<0 || (LightPosition + rate*Direction)>255)
  {
    Direction *= -1;
  }
  LightPosition += rate*Direction;
  Level = pow(LightPosition, 1.8)/84.2;
  
  analogWrite(pin, Level*(1-FadeLevel));
  
  if(pin == GREEN)
  {
    analogWrite(RED, Level * FadeLevel);
  }
  else
  {
    analogWrite(GREEN, Level * FadeLevel);
  }
  
  if(FadeLevel > 0)
  {
    FadeLevel -= 0.1;
  }
    
  PreviousState = pin;
}

//#################### Unpackage Data ####################
long unpackage(byte place)
{
  long value = 0;
  
  for(int i=place; i<place+4; i++)
  {
    value += long(Data[i]) << 8*(i-place);
  }
  
  return value;
}

//#################### Wireless Functions ####################
byte readData()
{
  byte Status;
  
  digitalWrite(CSN, LOW);
  Status = SPI.transfer(0x20 + 0x07);
  if(byte((Status << 1)) < 128)
  {
   SPI.transfer(B00001110);
   digitalWrite(CSN, HIGH);
   Status = 0;
  }
  else
  {
   SPI.transfer(B01111110);
   digitalWrite(CSN, HIGH);
   Status = 1; 
  
   digitalWrite(CE, LOW);
   digitalWrite(CSN, LOW);
   SPI.transfer(0x61);  
   for(int i=0; i<32; i++)
   {
     Data[i] = SPI.transfer(0x00);
   }
   digitalWrite(CSN, HIGH);
   digitalWrite(CE, HIGH);
  }
  return Status;
}

void setAddress(byte Channel)
{
  byte value = Channel;
  //This section for Rx address
  digitalWrite(CSN, LOW);
  SPI.transfer(0x20 + 0x0A);
  for(int i=0; i<5; i++)
  {
    SPI.transfer(Channel);
    Channel += 2;
  }
  digitalWrite(CSN, HIGH);
  
  //This section for Tx address
  digitalWrite(CSN, LOW);
  SPI.transfer(0x20 + 0x10);
  for(int i=0; i<5; i++)
  {
    SPI.transfer(value);
    value += 2;
  }
  digitalWrite(CSN, HIGH);
}

void SetupRegisters()
{
  byte reg[6][2] = {{0x00, B00001111}, //Set B7=0 for Tx, set 1 for Rx
                    {0x02, B00000001}, //Enable RX pipe 1
                    {0x04, B11111111}, //Retransmit wait + retries
                    {0x05, B01010100}, //Set RF CHANNEL
                    {0x06, B00100111}, //Set RF power and speed
                    {0x11, B00100000}}; //RF pipe payload: 32 bytes
  
  for(byte B=0; B<6; B++)
  {
    digitalWrite(CSN, LOW);
    SPI.transfer(0x20 + reg[B][0]);
    SPI.transfer(reg[B][1]);
    digitalWrite(CSN, HIGH);
    delay(1);
  }
}

Thanks in advance!

Deeksie

EDIT: Also, I did notice that when I plug the unit in, it can talk over serial, even if it hasn't been reset.