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?
#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)
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...
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
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.
#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.