I have a small program on the ATTiny85 pretty much working except for an issue I can not seem to get my head around.
The first use of getstuff(); works and I get the correct value displayed on my phones Bluetooth terminal.
The following question "What video length do you require (in whole seconds)?" is displayed but after typing an input and sending it to the attiny, I then do not get a response. It is like the code is stuck here.
I assume it may be my use of memset or something? Or missing a global variable? Or I dunno :|?
#include <SoftwareSerial.h>
SoftwareSerial btserial(0,1);
char gotstuff[10];
int i=0;
int data_variable=0;
void setup() {
btserial.begin(9600);
pinMode(4,OUTPUT);
}
void loop() {
int viewing_length=0;
int fps=0;
int t_int=0;
int event_time=0;
int ramping_wanted=0;
int test_shot=0;
int trigger=4;
btserial.println("Hello!");
delay(1000);
btserial.println("Test Shot? Milliseconds, 0 for No Test.");
test_shot=getstuff();
btserial.println(test_shot);
if (test_shot>0){
digitalWrite(trigger,HIGH);
delay(test_shot);
digitalWrite(trigger,LOW);
}
//==================Ask for video length.
btserial.println("What video length do you require (in whole seconds)?");
viewing_length=getstuff();
btserial.println(viewing_length);
//================= Ask for actual filming time!
btserial.println("What is the filming duration required (minutes)?");
event_time=getstuff();
btserial.println(event_time);
//================= Ask for FPS REQUIRED
btserial.println("What FPS (frames per second) are needed in the final video?");
fps=getstuff();
btserial.println(fps);
//=================== Show all settings - shot count, interval time etc.
btserial.println("\n These are the settings that will be used: ");
btserial.print("Final video length and FPS: ");
btserial.print(viewing_length);
btserial.print(" seconds @ ");
btserial.print(fps);
btserial.println(" fps.");
btserial.print("Shots: ");
btserial.print(viewing_length*fps);
btserial.print(" with ");
btserial.print((event_time*60)/(viewing_length*fps));
btserial.print(" interval seconds.\n");
btserial.println("");
}
//===THE GETSTUFF();==//
//function to get stuff from serial and parse it.
int getstuff(){
//====clear gotstuff to 0 in all 10 bytes.
memset(gotstuff,0,10);
//====while there is no available data to get...sit and wait.
while (btserial.available()==0){}
//====get the data from the serial and shove it in to a char array
i=0;
data_variable=0;
while(btserial.available()){
gotstuff[i]=btserial.read();
delay(25);
i++;
}
//===make data from array in to int and return.
sscanf(gotstuff, "%d", &data_variable);
return data_variable;
}
//===EOF===//
I don't see any diagnostic code in the sketch. Have you tried any? What results did you get?
If not, the first thing I'd suggest is to echo the received characters in getstuff(), before processing them with sscanf(), along with the number of characters received. Does it show what you expected?
Thanks for the suggestion. I will give it a go now.
I was under the impression when using say a function like print() in functions declared like "int function(){}" will cause the function to collapse as it has "returned" something?
Delta_G:
I would also recommend getting those constant strings out of SRAM. You only get 512 bytes of RAM memory on a tiny85. Don't waste it on constant strings in print statements. Once you run out of RAM, there is no debugging the program anymore.
Awesome little tip! Never knew that. Down to 148 bytes used of SRAM.
Ok, well I have edited my getstuff() to give a softwareserial.print.
On the first iteration it is used in my main{}/loop{}, it acts as I would expect and how I would like. It reads the values from the software serial, adds them to a char array one at a time.
int getstuff(){
//====clear gotstuff to 0 in all 10 bytes.
memset(gotstuff,0,10);
//====while there is no available data to get...sit and wait.
while (btserial.available()==0){}
//====get the data from the serial and shove it in to a char array
i=0;
data_variable=0;
while(btserial.available()){
gotstuff[i]=btserial.read();
//debugprint
btserial.println(gotstuff[i]);
//======
delay(25);
i++;
}
gotstuff[i]={'\0'};
//===make data from array in to int and return.
sscanf(gotstuff, "%d", &data_variable);
return data_variable;
}
//===EOF===//
Then same problem, second iteration...nothing. It is like it does not even begin to read the serial data?
I got the output in hex to ensure I was definitely getting absolutely nothing. Things in red are my inputs and the blue is the received from the bluetooth module:
Delta_G:
I would also recommend getting those constant strings out of SRAM. You only get 512 bytes of RAM memory on a tiny85. Don't waste it on constant strings in print statements. Once you run out of RAM, there is no debugging the program anymore.
For some reason....and I can not thank you enough...but my program seems to work now :S?
Had I just filled the SRAM causing something to break?
AWOL:
Another way of saving precious RAM is to review your variables.
Do they all need to be "int"s, or could some be "byte" or "char"?
Thanks. Does this apply to all variables once declared or just global variables?
Is a variable, when not in use any more...overwritten? I have no idea how assemblers work etc but assumed the final made machine code would know when variables can be scrapped?
Having a browse on google now :).
I guess I am just using some things as like "flags" such as
int ramping_wanted=0;
Which could be saved as a single byte (say 0b00000001) taking less space?
All variables consume RAM, whether static/global, on the heap or on the stack.
If you've got several boolean (true/false) flags, it may be expedient to make them individual bits, and combine them into a single byte.
AWOL:
All variables consume RAM, whether static/global, on the heap or on the stack.
If you've got several boolean (true/false) flags, it may be expedient to make them individual bits, and combine them into a single byte.
Sounds like a plan. If I have 4-5 flags...according to wiki (Integer (computer science) - Wikipedia) that is a good 2 bytes each...so another 10 ish bytes saved? Mind this is only 2% of my 512 bytes available?
Is it not worth it to carry on using int as it is easier to code with...taking up program space in the conversions etc?
Is it not worth it to carry on using int as it is easier to code with..
If "int" is appropriate, use it, but if you don't need numbers that run -32768 to 32767, don't use it.
For instance, is frames per second ever likely to approach 255?
No?
So, use a byte.
"gotstuff" contains, at most, 10 characters, yet the index "i" has a range -32768 to 32767.
AWOL:
If "int" is appropriate, use it, but if you don't need numbers that run -32768 to 32767, don't use it.
For instance, is frames per second ever likely to approach 255?
No?
So, use a byte.
"gotstuff" contains, at most, 10 characters, yet the index "i" has a range -32768 to 32767.
Thank you so much. I am getting this whole coding thing bit by bit (pun intended).
My next panic is getting the whole interupts working on a second attiny85...decided that software-serial or even bit banging 2 attinys together would be nice to allow one to do signal measurement while the other plays maths.
Johnny010:
Sounds like a plan. If I have 4-5 flags...according to wiki (Integer (computer science) - Wikipedia) that is a good 2 bytes each...so another 10 ish bytes saved? Mind this is only 2% of my 512 bytes available?
Is it not worth it to carry on using int as it is easier to code with...taking up program space in the conversions etc?
The code to utilize bits within a byte for boolean logic doesn't sacrifice that much program space. You can just create masks and compare against the bits. Ultimately RAM is more important when you are first designing your program.
If you are only going to use numbers, then including sscanf( ) is a big overhead.
I'd write something like this:
int getstuff(){
int answer=0 ;
//====while there is no available data to get...sit and wait.
while (btserial.available()==0){}
while(btserial.available()){
char c = btserial.read() ;
if ( c >= '0' && c<='9' ) answer=(10*answer)+(c-'0');
delay(25);
}
return answer ;
}
//===EOF===//
Actually, I'd probably try to avoid using delay(), but this approach is reasonable, and no less fault-tolerant than your method.
Please don't use DropBox. Attach your images to your post. I got this error:
Something went wrong. Don't worry, your files are still safe and the Dropboxers have been notified. Check out our Help Center and forums for help, or head back to home.
I don't want to wrangle with that stuff. You can attach images to the forum here.