Erratic behaviour with software serial and eeprom, attiny 84, tinyisp

Hi, not sure where to post this but I have a feeling coding badly, erni and the likes are hanging out here mor than in the programming section.

I have had some help putting toghether parts of my project and now I am putting the code together and it starts to get erratic.

My aim is to use a attiny84 to take temp-measurements and store them using eeprom. The tiny is in this phase hooked up to a small board with a cr2032 battery, a led and a button. Temperature storage should start when the button is pressed so that a measurement is taken every x milliseconds until memory full or button is pressed again. The n the tiny is removed from its socket and put into the tinyISP setup (a different board shielded to the arduino) where I can use software serial to unload the data.

For now I am only testing the program with the tiny connected to the arduino and I have gotten it to work as expected, sortof. All the functionality has been shown so there is no problem with the concept or the general idea, however depending on where I put delays parts of the code freezes the arduino or makes it skip to an unrelated place.
Example output from serial monitor:

--- Monitor starting --- //OK after sending "!" 
Starting Temp reading    // OK after sending "T" to start temp reading
282                                     /* OK this is the raw temperature data from the chip, however after this nothing more is written to serial first a 1 should be sent and then a new reading after 2 sec onds followed by a 2*/
Starting Temp reading   // OK after resending a "T"
282                                 // OK
1                                       //OK This one indicates the adress pointer to eeprom , no more reading though
Starting Temp reading   //resending "T"
282                                   //OK
1                                                         //OK, this 1 probably means  that the code has reset since it is not a 2 or the eeprom has not been written to.
I don't know what to do with : /*WTF the code for this is default action for the switch to handle input from the serial monitor. Some serial info is available but is not a charcter if I send a "g" I see a g here after the colon.  The following four rows are following the code.*/
Send a single 'T' to start temperature reading
Send a single 'R' to reset eeprom counter
Send a single 'S' to start temperature sending
Send a single 'X' to stop temperature sending
282           / /temp Reading 2
2                //stored in eeprom 2
I don't know what to do with : // see above
Send a single 'T' to start temperature reading
Send a single 'R' to reset eeprom counter
Send a single 'S' to start temperature sending
Send a single 'X' to stop temperature sending
281           //temp Reading 3
3               //stored in eeprom 3
I don't know what to do with :Send a single 'T' to start temperature reading
Send a single 'R' to reset eeprom counter
Send a single 'S' to start temperature sending
Send a single 'X' to stop temperature sending
282                                                  // unwanted stop of the code 
Starting Temp sending                    // OK sending a "S"
mi l l i s   b e t w e e n   r e a d i n g s :   2000 // the letters are OK and the value, but copying the text(or rather pasting here) does not work so there is some ascii code sent that looks like a space between the letters.
HE                    //This should read HERE but is broken

The behaivour described above is an example of strange behaviour. The code has worked almost as I wanted but with some myserial.println()s commented out. Am I flooding the softwareserial or is there something else I have missed?

The code:

#include <SoftwareSerial.h>
#include <core_adc.h>
#include <EEPROM.h>

const int buttonPin = 2;    // the number of the pushbutton pin
const int redPin = 10;// the number of the RED pin
const int powerPin = 1;  //Pin to power pushbutton
int redState = LOW;         // the current state of the output pin
boolean ledFlash = false;    // should the led be flashed
long flashStartTime = 0;      // to decide when to turn flash of
int flashDelay = 250;         //how long the flash of the led should be in millisecs
int buttonState;             // the current reading from the button pin
int lastButtonState = LOW;   // the previous reading from the button pin
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;  // the debounce time; increase if the output flickers
int tempDelay = 2000;  //Time in millisecs between temperature readings
long lastTemp = 0;   // Millis() time of last temperature reading 
const int rx=4;     // receive pin on attiny 
const int tx=PA5;   // MISO on attiny is also tx
SoftwareSerial mySerial(rx, tx); // setup of software serial
boolean takeTemp = false; // should tiny read temp or not
boolean sleepy = false; // should tiny go to sleep between readings

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(redPin, OUTPUT);
  pinMode(0,OUTPUT); 
  mySerial.begin(9600); // start software serial
  pinMode(powerPin,OUTPUT); //set powerpin as output
  digitalWrite(powerPin,HIGH); // enable pushbutton
  digitalWrite(0,HIGH); //flash led on tinyisp board
  delay(100); //flash time
  digitalWrite(0,LOW); //flash over 
  EEPROM.write(0,1); // use adress 0 to store eeprom adress pointer

}

void loop() {
  //Check state of buttonPin with debounce  
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  } 
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        takeTemp = !takeTemp; //tell tiny to start or stop taking temps when button is pressed
      }
    }
  }
  lastButtonState = reading;
  //temparature reading code
  if (takeTemp){
    if (millis()>lastTemp+tempDelay){
      int temp = temperatureRead();
      mySerial.println(temp); //remove this later
      int pos = EEPROM.read(0); //read current adress to write to
      delay(50);
      mySerial.println(int(pos)); //remove this later
      byte hitemp = temp/256; // if temp is higher than 255 hitemp will store 1, if higher than 511 store 2, etc.
      byte lotemp = temp%256; // store remainder in in lotemp
      EEPROM.write(pos,hitemp);//hitemp data are stored in lower part of memory
      EEPROM.write(pos+256,lotemp); //lotemp data are stored in higher part of memory
      pos++; //increment adress pointer
      if (pos>255)pos=255;
      EEPROM.write(0,pos); // write adress pointer 

      ledFlash=true; // set to flash the leds once
      lastTemp=millis();
    }  
  }


  //code for led flashing
  if (ledFlash){
    switch (redState){ //redstate is the current state of leds
    case LOW :

      flashStartTime = millis();
      redState = HIGH;
      break;

    case HIGH :
      if (millis() > flashStartTime + flashDelay){
        redState = LOW;
        ledFlash = false; // turn off ledFlash since the leds have finished the flash 
        break;
      }
    }
  }
  //set leds
  digitalWrite(redPin,redState);
  digitalWrite(0,redState);

  //serial communication
  if(mySerial.available()>0){ //take in command from serial monitor
    byte cmd = mySerial.read();
  /*  while(mySerial.available()>0){
      mySerial.read(); //discard all trailing characters.
      delay(10);
    }*/
    switch (cmd) { 
    case 82 : // R
      mySerial.println("Resetting eeprom counter");
      EEPROM.write(0,1); 
      break; 
    case 83 : // S
      mySerial.println("Starting Temp sending");
      sendTempData(); 
      break;
    case 84 : // T
      mySerial.println("Starting Temp reading");
      delay(20);
      takeTemp=true; //Set to tell the tiny to read temps 
      break; 
    case 88 : // X
      mySerial.println("Stopping Temp reading");
      takeTemp=false; //tell the tiny to stop taking temps.
      break;
    default : //show menu if a different character is received 
      mySerial.print("I don't know what to do with :");
      delay(50);
      mySerial.println(cmd);
      mySerial.println("Send a single 'T' to start temperature reading");
      delay(50);
      mySerial.println("Send a single 'R' to reset eeprom counter");
      delay(50);
      mySerial.println("Send a single 'S' to start temperature sending");
      delay(50);
      mySerial.println("Send a single 'X' to stop temperature sending");
      delay(50);
    }
  }


}


void sendTempData()
{
  int temp;
  byte hitemp;
  byte lotemp;
  int pos = EEPROM.read(0);
  delay(50);
  mySerial.print("millis between readings: ");
  mySerial.println(tempDelay);
  delay(100);
  mySerial.println("HERE");
  mySerial.println(int(pos));
  for(int i=1; i<pos; i++){
    hitemp = EEPROM.read(i);
    lotemp = EEPROM.read(i+256);
    temp = int(hitemp)*256+int(lotemp);
    mySerial.println(int(i));
    delay(20);
    mySerial.println(temp);
  }
  //while(temp = epprom.read(i)!=255)
  //read from eeprom
}
int temperatureRead( void )
{
  ADC_SetVoltageReference( ADC_Reference_Internal_1p1 );
  ADC_SetInputChannel( ADC_Input_ADC8 );

  ADC_StartConversion();

  while( ADC_ConversionInProgress() );

  return( ADC_GetDataRegister() );
}

I think the first thing I would consider is tuning the internal osccilator.
If it is too much off it will cause trouble with SoftwareSerial (or any other serial comm)

You could use TinyTuner2 to do the tuning.

http://forum.arduino.cc/index.php?topic=173408.0

You could use TinyTuner2 to do the tuning.

Trying that now. I have changed tinyisp to enable tinydebugknockbang and it is loaded. The code example "printusingknockbang" compiles and loads but I don't get any output on the serial...

From the knockbang header file It seems that the knockbang is using the ordinary miso on the tiny, so I should get some output even if I don't connect any oscillator on xtal2, right? Like for erni here: ?http://forum.arduino.cc/index.php?topic=173408.msg1288092#msg1288092

How do I setup tinyisp to give a tuning signal like coding badly says here: Tiny Core 2 + ATtiny861 - #2 by Coding_Badly - Microcontrollers - Arduino Forum?

Edit: removed some confused text...

Hasseklas:
The n the tiny is removed from its socket and put into the tinyISP setup (a different board shielded to the arduino) where I can use software serial to unload the data.

Software serial never causes anything other than problems:

Use I2C, SPI, anything other than software serial.

From the knockbang header file It seems that the knockbang is using the ordinary miso on the tiny, so I should get some output even if I don't connect any oscillator on xtal2, right?

Yes that is right.

The the _TinyISP_BuildOptions should look like this when you are using KnockBang
Remember to comment out this in the TinyISP

//#include <SoftwareSerial.h>
/Set to 1 if using KnockBang and comment out #include <SoftwareSerial.h> in TinyISP
   #define RELAY_KNOCK_BANG_ENABLED 1
 
//Set to 1 if using Serial Relay, and uncomment #include <SoftwareSerial.h> in TinyISP
   //Transmit on Arduino is A0
   #define RELAY_SERIAL_ENABLED  0
 
//Set to 1 if using TinyTuner2

   //Tuning signal pin 3 on UNO, connect to xtal2 on target
   #define TUNING_SIGNAL_ENABLED  1

And rember to set the Serila monitor at 19.200

Have done all that except for the tuning signal. have to fix the hardware for that first. I.e. set it up on a breadboard or do some soldering.

However, something really strange is happening. On my tiny programing board I have an LED connected to pin 0 to use for some debugging and to flash inside setup to signal that upload is ready.

I added code to light the LED to the printusingknockbang example and it gets stuck within the call to OutputOSCCALAssignment(); in main.
I have code to flash the LED right Before and right after the call but there is only one flash end then nothing.

Still stuck here.

This code works:

 #include <SoftwareSerial.h>
// Attiny84 and TinyISP Serial Relay
#include <core_adc.h>
#include <EEPROM.h>
int i=0;
const int rx=3; //receive pin on attiny pic any
const int tx=PA5; //MISO on attiny is also tx

SoftwareSerial mySerial(rx, tx);
void setup() { 
  mySerial.begin(9600);
}

void loop() {
 
  if(mySerial.available()>0){
    int b=mySerial.read()  ;
  b = temperatureRead();
        byte hitemp = b/256; // if temp is higher than 255 hitemp will store 1, if higher than 511 store 2, etc.
      byte lotemp = b%256; // store remainder in in lotemp
    mySerial.print(i);
    mySerial.print(":");
    mySerial.println(b);
      EEPROM.write(i,hitemp);//hitemp data are stored in lower part of memory
      EEPROM.write(i+256,lotemp); 
    i++;
  }

  for (int j=0;j<i;j++){
    byte hitemp = EEPROM.read(j);
    delay(100);
    byte lotemp = EEPROM.read(j+256);
    delay(100);
    int temp = int(hitemp)*256+int(lotemp);
   mySerial.print(j);
   mySerial.print(": ");
    mySerial.println(temp);
    
  }
  mySerial.println(millis());
  delay(1000);

}
int temperatureRead( void )
{
  ADC_SetVoltageReference( ADC_Reference_Internal_1p1 );
  ADC_SetInputChannel( ADC_Input_ADC8 );

  ADC_StartConversion();

  while( ADC_ConversionInProgress() );

  return( ADC_GetDataRegister() );
}

This does not:

#include <SoftwareSerial.h>
#include <core_adc.h>
#include <EEPROM.h>

const int buttonPin = 2;    // the number of the pushbutton pin
const int redPin = 10;// the number of the RED pin
const int powerPin = 1;  //Pin to power pushbutton
int redState = LOW;         // the current state of the output pin
boolean ledFlash = false;    // should the led be flashed
long flashStartTime = 0;      // to decide when to turn flash of
int flashDelay = 250;         //how long the flash of the led should be in millisecs
int buttonState;             // the current reading from the button pin
int lastButtonState = LOW;   // the previous reading from the button pin
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;  // the debounce time; increase if the output flickers
int tempDelay = 2000;  //Time in millisecs between temperature readings
long lastTemp = 0;   // Millis() time of last temperature reading 
const int rx=3;     // receive pin on attiny 
const int tx=5;   // MISO on attiny is also tx
SoftwareSerial mySerial(rx, tx); // setup of software serial
boolean takeTemp = false; // should tiny read temp or not
boolean sleepy = false; // should tiny go to sleep between readings

void setup() {
  OSCCAL = 0x78;
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, LOW);
  pinMode(redPin, OUTPUT);
  pinMode(0,OUTPUT); 
  mySerial.begin(9600); // start software serial
  pinMode(powerPin,OUTPUT); //set powerpin as output
  digitalWrite(powerPin,HIGH); // enable pushbutton
  digitalWrite(0,HIGH); //flash led on tinyisp board
  delay(100); //flash time
  digitalWrite(0,LOW); //flash over 
  EEPROM.write(0,1); // use adress 0 to store eeprom adress pointer

}

void loop() {
  //Check state of buttonPin with debounce  
  int reading = digitalRead(buttonPin);
  /* if (reading != lastButtonState) {
   lastDebounceTime = millis();
   } 
   if ((millis() - lastDebounceTime) > debounceDelay) {
   if (reading != buttonState) {
   buttonState = reading;
   // only toggle the LED if the new button state is HIGH
   if (buttonState == HIGH) {
   takeTemp = !takeTemp; //tell tiny to start or stop taking temps when button is pressed
   }
   }
   }
   */
  lastButtonState = reading;
  //temparature reading code
  if (takeTemp){

    if (millis()>lastTemp+tempDelay){
      int temp = temperatureRead();
      mySerial.println(temp); //remove this later
      int pos = EEPROM.read(0); //read current adress to write to
      delay(50);
      mySerial.println(int(pos)); //remove this later
      byte hitemp = temp/256; // if temp is higher than 255 hitemp will store 1, if higher than 511 store 2, etc.
      byte lotemp = temp%256; // store remainder in in lotemp
      EEPROM.write(pos,hitemp);//hitemp data are stored in lower part of memory
      EEPROM.write(pos+256,lotemp); //lotemp data are stored in higher part of memory
      pos++; //increment adress pointer
      if (pos>255)pos=255;
      EEPROM.write(0,pos); // write adress pointer 

      ledFlash=true; // set to flash the leds once
      lastTemp=millis();
    }  
  }


  //code for led flashing
  if (ledFlash){
    switch (redState){ //redstate is the current state of leds
    case LOW :

      flashStartTime = millis();
      redState = HIGH;
      break;

    case HIGH :
      if (millis() > flashStartTime + flashDelay){
        redState = LOW;
        ledFlash = false; // turn off ledFlash since the leds have finished the flash 
        break;
      }
    }
  }
  //set leds
  digitalWrite(redPin,redState);
  digitalWrite(0,redState);

  //serial communication
  if(mySerial.available()>0){ //take in command from serial monitor
    byte cmd = mySerial.read();
    /*  while(mySerial.available()>0){
     mySerial.read(); //discard all trailing characters.
     delay(10);
     }*/
    switch (cmd) { 
    case 82 : // R
      mySerial.println("Resetting eeprom counter");
      EEPROM.write(0,1); 
      break; 
    case 83 : // S
      mySerial.println("Starting Temp sending");
      sendTempData(); 
      break;
    case 84 : // T
      mySerial.println("Starting Temp reading");
      delay(20);
      takeTemp=true; //Set to tell the tiny to read temps 
      break; 
    case 88 : // X
      mySerial.println("Stopping Temp reading");
      takeTemp=false; //tell the tiny to stop taking temps.
      break;
    default : //show menu if a different character is received 
      mySerial.print("I don't know what to do with :");
      delay(50);
      mySerial.println(cmd);
      mySerial.println("Send a single 'T' to start temperature reading");
      delay(50);
      mySerial.println("Send a single 'R' to reset eeprom counter");
      delay(50);
      mySerial.println("Send a single 'S' to start temperature sending");
      delay(50);
      mySerial.println("Send a single 'X' to stop temperature sending");
      delay(50);
    }
  }


}


void sendTempData()
{
  int temp;
  byte hitemp;
  byte lotemp;
  int pos = EEPROM.read(0);
  delay(100);
  mySerial.print("millis between readings: ");
  mySerial.println(tempDelay);
  mySerial.println(lastTemp);
  mySerial.println((millis()));
  // delay(100);
  //mySerial.println("HERE");
  //delay(100);
  //mySerial.println(int(pos));
  for(int i=1; i<pos; i++){
    hitemp = EEPROM.read(i);
    delay(100);
    lotemp = EEPROM.read(i+256);
    delay(100);
    temp = int(hitemp)*256+int(lotemp);
    mySerial.println(int(i));
    delay(100);
    mySerial.println(temp);
  }
  mySerial.println(lastTemp);
  mySerial.println(long(millis()));
  //while(temp = epprom.read(i)!=255)
  //read from eeprom
}
int temperatureRead( void )
{
  ADC_SetVoltageReference( ADC_Reference_Internal_1p1 );
  ADC_SetInputChannel( ADC_Input_ADC8 );

  ADC_StartConversion();

  while( ADC_ConversionInProgress() );

  return( ADC_GetDataRegister() );
}

This code makes the following printout in serial monitor:

--- Monitor starting ---
Starting Temp reading  / OK after sending "T"
273
1
273
2
273
3
Stopping Temp Reading //OK after sending "X"
Starting Temp sending // OK after sending  "S"
millis between readings: 2000 // OK
8626 //OK this is the value lastTemp
3691105552 //NOT OK this is the millis()
1
273
2
273
3
273
8626
-603861567 //millis() again

Exactly the same hardware setup.

The second code still makes some other erratic errors aswell.