Weird things with Switch Case Arduino - arduino

Well I know it sounds pretty weird, but I made code in Arduino which works find when i just use an if statement for every different option. But that's what switch cases are for, so I tried it and for some weird reason it goes into and executes the code for standbyStatus==0 and for standbyStatus==1, but for standbyStatus==2 or in default, nothing is executed whatsoever. Note that the variable standbyStatus is set to 2 by the code for status 1. I can check that over the serial monitor, but the test Serial.print("case 2.1"); in the 2 -code doesn't appear. Only END of standbymanager. Again, when I use if, everything works as it should. Here is first the code with if and then the same code just as a switch case:
Also, that method is called over and over again. This is my loop.
void loop()
{
t= millis();
newAudio();
calcAudioScale();
if(standbyStatus==0){changeLEDs();}
standbymanager();
}
That method is basicly checking if there is some sound for like 40ms or sth, and if there is not, it'll change to standbyStatus One, which is a smooth dim up of the LEDs, which will be interrupted if there is sound, but if there isn't, it'll change to standbyStatus Two, which is just a solid light and checking just every second if there is sound. If so, it'll change back to stabdbyStatus zero.
Code #1 'IF':
void standbymanager()
{
if(standbyStatus==0)
{
Serial.print(" ");
Serial.print("case0");
if(audio[standbyTrigger]<0)
{
idleCounter++;
}
if(idleCounter>40)
{
standbyStatus = 1;
}
}
if(standbyStatus==1)
{
Serial.print(" ");
Serial.print("case1");
idleCounter = 0;
float power = 0;
for(int i=0; i<100; i++)
{
if(audio[standbyTrigger]>0)
{
standbyStatus = 0;
return;
}
power = i/100;
analogWrite(red, 255 - r*power);
analogWrite(green, 255 - g*power);
analogWrite(blue, 255 - b*power);
delay(20);
}
standbyStatus = 2;
return;
}
if(standbyStatus==2)
{
Serial.print(" ");
Serial.print("case 2.1");
if(audio[standbyTrigger]>10)
{
standbyStatus = 0;
return;
}
analogWrite(red, 255 - r);
analogWrite(green, 255 - g);
analogWrite(blue, 255 - b);
Serial.print(" ");
Serial.print("case2.2");
delay(1000);
return;
}
Serial.print(" ");
Serial.print("END of StandbyManager");
}
Code #2 'Switch Case'
void standbymanager()
{
switch(standbyStatus)
{
case 0:
Serial.print(" ");
Serial.print("case0");
if(audio[standbyTrigger]<0)
{
idleCounter++;
}
if(idleCounter>40)
{
standbyStatus = 1;
}
break;
case 1:
Serial.print(" ");
Serial.print("case1");
idleCounter = 0;
float power = 0;
for(int i=0; i<100; i++)
{
if(audio[standbyTrigger]>0)
{
standbyStatus = 0;
break;
}
power = i/100;
analogWrite(red, 255 - r*power);
analogWrite(green, 255 - g*power);
analogWrite(blue, 255 - b*power);
delay(20);
}
standbyStatus = 2;
break;
case 2:
Serial.print(" ");
Serial.print("case 2.1");
if(audio[standbyTrigger]>0)
{
standbyStatus = 0;
break;
}
analogWrite(red, 255 - r);
analogWrite(green, 255 - g);
analogWrite(blue, 255 - b);
Serial.print(" ");
Serial.print("case2.2");
delay(1000);
break;
default:
standbyStatus=0;
Serial.print(" ");
Serial.print("default");
delay(1000);
break;
}
Serial.print(" ");
Serial.print("END of StandbyManager");
}

I guess the errors come from case 1:
variables can't be declared inside a case statement
the break inside the for doesn't break from the switch statement
You can refactor it to:
case 1:
{
Serial.print(" ");
Serial.print("case1");
idleCounter = 0;
float power = 0;
bool flag = false;
for(int i=0; i<100; i++)
{
if(audio[standbyTrigger]>0)
{
standbyStatus = 0;
flag = true;
break;
}
power = i/100;
analogWrite(red, 255 - r*power);
analogWrite(green, 255 - g*power);
analogWrite(blue, 255 - b*power);
delay(20);
}
if (flag == false) {
standbyStatus = 2;
}
break;
}

You're probably changing standbyStatus 0 to 1 here:
if(standbyStatus==0)
{
Serial.print(" ");
Serial.print("case0");
if(audio[standbyTrigger]<0)
{
idleCounter++;
}
if(idleCounter>40)
{
standbyStatus = 1;
}
}
then it's normal to enter this if statement:
if(standbyStatus==1)
{
Serial.print(" ");
Serial.print("case1");
idleCounter = 0;
float power = 0;
for(int i=0; i<100; i++)
{
if(audio[standbyTrigger]>0)
{
standbyStatus = 0;
return;
}
power = i/100;
analogWrite(red, 255 - r*power);
analogWrite(green, 255 - g*power);
analogWrite(blue, 255 - b*power);
delay(20);
}
standbyStatus = 2;
return;
}
and second version of your code you use switch case, as the name suggest you only select one. Therefore standbyStatus will be updated but not going to enter other cases.
Edit:
Be aware that two codes are doing different things, code 1 can change standbyStatus and enter other if statements, and it returns after setting standbyStatus. Code 2 doesn't return in cases it only breaks the loop not entire case. Also Code 2 is not going to enter different blocks like in Code 1 (for single function call).

Related

Stepper Motor not rotating properly/precisely

I would like to control a tray to move back and forth automatically between several positions automatically.
Hardware: arduino nano / mega, TMC2209 and TB6600 stepper motor drivers, stepper motor 23HS84830.
Power Supply: 12V/5A
Problem: I wrote the code and noticed that although the interval between positions was fixed, the tray would move a little bit more each time therefore missing the position. At the last position it would be really off position.
Attempted Solutions: To solve this I decided to write a serial command sketch that would allow me to simulate this behaviour, define intervals, number of positions, cycles, laps, microstepping, see code below.
I had just run a sequence and made it back to the main menu. these are all the options that can be configured.
Made some trials and noticed that my sketch was outputing exactly what I configured in the right way (see picture of logic analyzer below).
In this picture the what happens is:
stepper motor rotates 5 laps (8000 steps) and waits 0,5 seconds before rotating again. repeats 5 times.
changes direction
does the same as step 1
What I did to try and solve the problem so far:
changed between TMC2209 and TB6600 to see if the problem would be the driver: it wasn't happens with both drivers
checked with the logic analyzer if the problem was the code: it wasn't, output of code is consistent and easily measurable
reviewed the connections of the stepper motor coils. not a problem and according to the motor datasheet/stepper motor driver datasheet.
At this moment, I cannot understand why the motor is not moving correctly and I would appreciate experienced support to solve this since it seems quite trivial but I cannot find the bug.
Thanks!
int PUL=4; //define Pulse pin
int DIR=3; //define Direction pin
int ENA=2; //define Enable Pin
#define left 1
#define right 0
#define LEFT 1
#define RIGHT 0
int steps_per_revolution = 200;
int minutes = 60;
long int input_value = 0;
long int _speed = 0;
long int temp_speed_rpm = 0;
long int speed_rpm = 0;
long int steps = 0;
int cycles = 0;
int positions = 0;
long int laps = 0;
long int rpm = 0;
int microstepping = 0;
long int total_laps = 0;
// Serial Commands
String command;
String inString = "";
// control flag to show the menu
boolean refresh_commands = false;
// DIRECTION LOW - MOVES RIGHT
// DIRECTION HIGH - MOVES LEFT
void setup() {
pinMode (PUL, OUTPUT);
pinMode (DIR, OUTPUT);
pinMode (ENA, OUTPUT);
Serial.begin(115200);
menu_print();
}
void loop()
{
if(Serial.available()){
command = Serial.readStringUntil('\n');
if(command.equals("p")){
variable_print();
refresh_commands = true;
}
if(command.equals("ss")){
Serial.println("0");
_speed = input_data();
Serial.print(_speed);
Serial.println(" uS");
refresh_commands = true;
}
if(command.equals("ssr")){
Serial.println("ssr");
temp_speed_rpm = input_data();
_speed = calculate_speed(temp_speed_rpm);
refresh_commands = true;
}
if(command.equals("sd")){ // checks if one direction is set, changes and then changes back again
if(digitalRead(DIR) == HIGH)
{
change_direction(right);
Serial.println("Direction changed to: RIGHT");
}
else
{
if(digitalRead(DIR) == LOW)
{
change_direction(left);
Serial.println("Direction changed to: LEFT");
}
}
refresh_commands = true;
}
if(command.equals("sst")){
Serial.println("sst");
steps = input_data();
Serial.println(" ");
Serial.print(steps);
Serial.println(" - steps configured");
refresh_commands = true;
}
if(command.equals("sm")){
Serial.println("sm");
Serial.println("sm --> how many microsteps?");
microstepping = input_data();
Serial.println(microstepping);
refresh_commands = true;
}
if(command.equals("sp")){
Serial.println("sp");
positions = input_data();
Serial.println("sp --> Configure Positions");
Serial.println(positions);
refresh_commands = true;
}
if(command.equals("sc")){
Serial.println("sc");
cycles = input_data();
Serial.println("sc --> Configure Cycles");
Serial.println(cycles);
refresh_commands = true;
}
if(command.equals("sl")){
Serial.println("sl");
Serial.println("sl --> how many laps?");
laps = input_data();
Serial.print(laps);
refresh_commands = true;
}
if(command.equals("1")){
Serial.println("1");
change_direction(left);
steps = input_data(); // Asks before for how many steps to rotate and changes the value.
rotate_motor(steps);
refresh_commands = true;
}
if(command.equals("2")){
Serial.println("2");
change_direction(right);
steps = input_data(); // Asks before for how many steps to rotate and changes the value.
rotate_motor(steps);
refresh_commands = true;
}
if(command.equals("3")){
Serial.println("3");
change_direction(left);
rotate_motor(steps);
refresh_commands = true;
}
if(command.equals("4")){
Serial.println("4");
change_direction(right);
rotate_motor(steps);
refresh_commands = true;
}
if(command.equals("rs")){
Serial.println("rs --> Run Sequence");
variable_print();
delay(3000);
total_laps = laps * steps_per_revolution * microstepping;
// run the planned sequence
run_sequence(cycles, positions);
refresh_commands = true;
}
if(command.equals("rl")){
Serial.println("rl");
Serial.println("rl --> how any laps? ");
variable_print();
delay(3000);
total_laps = laps * steps_per_revolution * microstepping;
// calculate laps and activate motor
run_laps();
refresh_commands = true;
}
else{
Serial.println("Invalid command");
refresh_commands = true;
}
refresh_commands = true; // added here to remove from all other commands
}
if (refresh_commands == true){
menu_print();
refresh_commands = false;
}
}
void run_sequence(int cycles, int positions){
int j = 0;
for(j=0; j<cycles; j++)
{
Serial.print("Cycle: ");
Serial.println(j);
// Start always moving to LEFT
change_direction(left);
Serial.println("Direction changed to: LEFT");
for(int i=0; i<positions; i++)
{
Serial.print("FWD Pos.: ");
Serial.println(i);
rotate_motor(total_laps);
delay(500);
}
delay(1000);
//change_direction(right);
change_direction(right);
Serial.println("Direction changed to: RIGHT");
delay(100);
for(int i=0; i<positions; i++)
{
Serial.print("BWD Pos.: ");
Serial.println(i);
rotate_motor(total_laps);
delay(500);
}
}
}
void run_laps(){
// long int total_laps = 0;
// total_laps = laps * steps_per_revolution * microstepping;
// moved to the main cycle and changed run_sequence to include the laps
Serial.print("Total Laps Steps: "); // to be tested.
Serial.println(total_laps);
Serial.print("Laps: "); // to be tested.
Serial.println(laps);
Serial.print("Steps/rev: "); // to be tested.
Serial.println(steps_per_revolution);
Serial.print("MicroStepping: "); // to be tested.
Serial.println(microstepping);
// change direction
change_direction(left);
// rotate motor
rotate_motor(total_laps); // variables must be long otherwise we cannot do the same number of steps as others
delay(1000);
// change direction
change_direction(right);
// rotate motor
rotate_motor(total_laps);
Serial.print(laps);
Serial.println(" - Laps completed.");
}
int input_data(){
int inChar = 0;
boolean flag = false;
Serial.println("How many?");
Serial.println(" ");
do{
while (Serial.available() > 0) {
inChar = Serial.read();
if (isDigit(inChar)) {
// convert the incoming byte to a char and add it to the string:
inString += (char)inChar;
}
// if you get a newline, print the string, then the string's value:
if (inChar == '\n') {
input_value = inString.toInt();
// clear the string for new input:
inString = "";
flag = true;
}
// // if the received char is an 'Z', then it triggers a flag to leave the menu
// if(inChar == 'Z')
// {
// flag = true;
// }
}
}while(!flag);
return input_value;
}
void rotate_motor(long int motor_steps){
Serial.print("Starting Rotation --> ");
Serial.println(motor_steps);
long int i=0;
digitalWrite(ENA, LOW);
for (i=0; i<motor_steps; i++)
{
digitalWrite(PUL,HIGH);
delayMicroseconds(_speed);
digitalWrite(PUL,LOW);
delayMicroseconds(_speed);
}
Serial.print("i --> ");
Serial.print(i);
digitalWrite(ENA, HIGH);
Serial.println("Finished rotation!");
}
void change_direction(bool direction){
delayMicroseconds(500);
digitalWrite(ENA,HIGH);
delayMicroseconds(100);
digitalWrite(DIR,direction);
delayMicroseconds(500);
digitalWrite(ENA,LOW);
delayMicroseconds(100);
Serial.print("Read Dir: ");
Serial.println(digitalRead(DIR));
}
void menu_print(){
Serial.println(" ");
Serial.println("p --> Display Parameters");
Serial.println("ss --> Set Speed (tON/tOFF)");
Serial.println("ssr --> Set Speed (RPM)");
Serial.println("sd --> Configure direction");
Serial.println("sst --> Set Steps");
Serial.println("sm --> Set MicroStepping (default = 1)");
Serial.println("sp --> Set Positions");
Serial.println("sc --> Set Cycles");
Serial.println("sl --> Set Laps");
Serial.println("1 --> Move LEFT x steps");
Serial.println("2 --> Move RIGHT x steps");
Serial.println("3 --> Move LEFT 1 position");
Serial.println("4 --> Move RIGHT 1 position");
Serial.println("rs --> Run Sequence");
Serial.println("rl --> Run Laps");
Serial.println(" ");
}
void variable_print(){
Serial.print("Speed: ");
Serial.print(_speed);
Serial.println(" us");
Serial.print("Speed: ");
Serial.print(temp_speed_rpm);
Serial.println(" RPM");
Serial.print("Steps: ");
Serial.println(steps);
Serial.print("Microstepping: ");
Serial.println(microstepping);
Serial.print("Positions: ");
Serial.println(positions);
Serial.print("Cycles: ");
Serial.println(cycles);
Serial.print("Laps: ");
Serial.println(laps);
Serial.print("Direction: ");
read_direction();
}
bool read_direction(){
//bool dir_state = 0;
if(digitalRead(DIR) == HIGH)
{
Serial.println("LEFT");
}
else
{
if(digitalRead(DIR) == LOW)
{
Serial.println("RIGHT");
}
}
return digitalRead(DIR);
}
long int calculate_speed(long int _speed){
float steps_per_second = 0; // truncating a float to int -> error chance here
float temp_speed = 0;
Serial.print("FUNCTION: Calculate_speed: ");
Serial.print(_speed);
Serial.println(" RPM");
steps_per_second = (_speed * steps_per_revolution) / minutes;
Serial.print("FUNCTION: steps_per_second: ");
Serial.println(steps_per_second);
temp_speed = (1 / steps_per_second);
temp_speed = temp_speed / 2; // to find Ton and Toff
temp_speed = temp_speed / 0.000001; // to convert to microseconds (input to delayMicroseconds() function)
temp_speed = (int) temp_speed;
// Serial.print("FUNCTION: _speed in microseconds: ");
// Serial.print(temp_speed,5);
// Serial.println(" uS");
Serial.print("FUNCTION: _speed in microseconds: ");
Serial.print(temp_speed);
Serial.println(" uS");
return temp_speed;
}

Arduino Ethernet W5100 device stops responding after a few days

I am running a simple web server (static IP) based on the default web server example, which is occasionally interrupted by an external input (eg. RFID reader) which sends data as a client to another server in the local network and starting the server again. the device runs as intended for a few days but then stops responding to pin inputs, accessing the server page seems to get it back on line (not sure about this) otherwise I am forced to manually reset when this happens.
Could using Serial Print(used during the debugging stage) without connecting a serial monitor be the issue?
test code:
/*
This program will decode the wiegand data from a HID RFID Reader (or, theoretically,
any other device that outputs weigand data).
The Wiegand interface has two data lines, DATA0 and DATA1. These lines are normally held
high at 5V. When a 0 is sent, DATA0 drops to 0V for a few us. When a 1 is sent, DATA1 drops
to 0V for a few us. There is usually a few ms between the pulses.
Your reader should have at least 4 connections (some readers have more). Connect the Red wire
to 5V. Connect the black to ground. Connect the green wire (DATA0) to Digital Pin 2 (INT0).
Connect the white wire (DATA1) to Digital Pin 3 (INT1). That's it!
Operation is simple - each of the data lines are connected to hardware interrupt lines. When
one drops low, an interrupt routine is called and some bits are flipped. After some time of
of not receiving any bits, the Arduino will decode the data.
*/
#include <Ethernet.h>
#include <SPI.h>
#include <EEPROM.h>
#define MAX_BITS 100 // max number of bits
#define WEIGAND_WAIT_TIME 3000 // time to wait for another weigand pulse.
unsigned char databits[MAX_BITS]; // stores all of the data bits
unsigned char bitCount; // number of bits currently captured
unsigned char flagDone; // goes low when data is currently being captured
unsigned int weigand_counter; // countdown until we assume there are no more bits
unsigned long facilityCode = 0; // decoded facility code
unsigned long cardCode = 0; // decoded card code
byte tr = 0; //testing trigger
byte ship[4]; //Home Center IP
byte wsip[4]; //Web Server IP
int scene[100]; //scene ID storage
//byte ptr = 0; //log pointer
byte ld = 0; //latest updated log
byte bc[20]; //Wiegand bitCount log
unsigned long wd[20]; //Wiegand data log
String readString1; //IP buffer
String tempstr = "{\r\n\"value\":\"";
String PostData = "{\r\n\"value\":\"1\"\r\n}"; //JSON data to send
// interrupt that happens when INTO goes low (0 bit)-2
void ISR_INT0()
{
Serial.print("0"); // uncomment this line to display raw binary
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
tr = 1;
}
// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1()
{
Serial.print("1"); // uncomment this line to display raw binary
if(bitCount<MAX_BITS)
databits[bitCount] = 1;
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
}
byte mac[] = { 0x00, 0xAB, 0xCB, 0xCD, 0xDE, 0x05 };
// byte ip[] = {192,168,4,101};
IPAddress ip(192, 168, 5, 211);
// byte gateway[] = {192,168,4,254};
// byte gateway[] = {192, 168, 5, 1};
// byte subnet[] = {255, 255, 255, 0};
// IPAddress server(192,168,4,100);
IPAddress sh(192, 168, 5, 65);
EthernetServer server(80); //server port arduino server will use
EthernetClient client;
char cnt1 = 0, cnt2 = 0;
void setup()
{
//pinMode(13, OUTPUT); // LED
pinMode(2, INPUT_PULLUP); // DATA0 (INT0)
pinMode(3, INPUT_PULLUP); // DATA1 (INT1)
Serial.begin(9600);
Serial.println("BioLite Net");
attachInterrupt(0, ISR_INT0, FALLING);
attachInterrupt(1, ISR_INT1, FALLING);
// binds the ISR functions to the falling edge of INTO and INT1
EEPROM.get(15, wsip);
IPAddress ip(wsip[0], wsip[1], wsip[2], wsip[3]);
net();
delay(10);
server.begin();
Serial.print(F("Web server is at "));
Serial.println(ip);
// Serial.print(F("server is at "));
// Serial.println(Ethernet.localIP());
EEPROM.get(10, ship);
IPAddress sh(ship[0], ship[1], ship[2], ship[3]);
Serial.print(F("Home Center is at "));
Serial.println(sh);
Serial.println(F("stored scenes are :"));
EEPROM.get(20, scene);
for (byte i = 0; i < 10 ; i++)
{
for (byte j = 0; j < 10 ; j++)
{
Serial.print((10 * i) + j);
Serial.print(" : ");
Serial.print(scene[(10 * i) + j]);
Serial.print(" ; ");
}
Serial.println();
}
EEPROM.get(310, bc);
EEPROM.get(330, wd);
EEPROM.get(305, ld);
byte temp = ld;
Serial.println(temp);
for (byte i = 0; i < 10 ; i++)
{
for (byte j = 0; j < 2 ; j++)
{
Serial.print(bc[temp]);
Serial.print(" : ");
Serial.print(wd[temp], BIN);
Serial.print(" ; ");
if (temp == 0)
temp = 20;
temp--;
}
Serial.println();
}
Serial.println();
/* temp = 19;
for (byte i = 0; i < 10 ; i++)
{
for (byte j = 0; j < 2 ; j++)
{
Serial.print(bc[temp]);
Serial.print(" : ");
Serial.print(wd[temp], BIN);
Serial.print(" ; ");
temp--;
if (temp < 0)
temp = 19;
}
Serial.println();
}*/
weigand_counter = WEIGAND_WAIT_TIME;
}
void loop()
{
// This waits to make sure that there have been no more data pulses before processing data
if (!flagDone) {
if (--weigand_counter == 0)
flagDone = 1;
}
// if we have bits and we the weigand counter went out
if (bitCount > 0 && flagDone) {
//if (tr == 1) {
tr == 0; delay(3000);
unsigned char i;
Serial.println();
if(bitCount>255) bitCount=255;
EEPROM.get(305, ld);
EEPROM.get(310, bc);
EEPROM.get(330, wd);
ld++;
if (ld > 19)
ld = 0;
Serial.println(ld);
// ptr += 5;
// ld = (ptr - 310) / 5;
bc[ld] = bitCount;
wd[ld] = 0;
for (i = 0; i < bitCount; i++)
{
Serial.print(databits[i]);
wd[ld] <<= 1;
wd[ld] |= databits[i];
}
EEPROM.put(305, ld);
EEPROM.put(310, bc);
EEPROM.put(330, wd);
Serial.println();
Serial.print("Read ");
Serial.print(bitCount);
Serial.print(" bits. ");
// we will decode the bits differently depending on how many bits we have
// see www.pagemac.com/azure/data_formats.php for mor info
if (bitCount == 35)
{
// 35 bit HID Corporate 1000 format
// facility code = bits 2 to 14
for (i = 2; i < 14; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 15 to 34
for (i = 14; i < 34; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 37)
{
// HID 37 bit format H10304
// facility code = bits 2 to 17
for (i = 1; i < 17; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 18 to 36
for (i = 17; i < 36; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 34)
{
// HID 34 bit format N1002
// facility code = bits 2 to 17
for (i = 1; i < 17; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 18 to 33
for (i = 17; i < 33; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 26)
{
// standard 26 bit format H10301
// facility code = bits 2 to 9
for (i = 1; i < 9; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 10 to 25
for (i = 9; i < 25; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 11)
{
// older Magstripe 11 bit format
// facility code = bits 6 to 9
for (i = 5; i < 9; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 1 to 5
for (i = 0; i < 5; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else {
// you can add other formats if you want!
Serial.println("Unable to decode.");
}
EEPROM.get(10, ship);
IPAddress sh(ship[0], ship[1], ship[2], ship[3]);
EEPROM.get(20, scene);
String tempstr = "{\r\n\"value\":\"";
String PostData = "{\r\n\"value\":\"1\",\"invokeScenes\":true\r\n}"; //JSON data to send
tempstr = tempstr + cardCode;
PostData = tempstr + "\",\"invokeScenes\":true\r\n}";
if (client.connect(sh, 80)) {
client.print("GET /api/sceneControl?id=");
client.print(scene[cardCode]);
client.println("&action=start HTTP/1.1");
auth(sh);
Serial.print("Scene ");
Serial.print(scene[cardCode]);
Serial.println(" treggered");
/* }
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
delay(3000);
Ethernet.begin(mac, ip);
if (Ethernet.localIP() != ip)
{
Serial.println(F("Failed to configure Ethernet using static IP"));
for (;;)
;
}
}
if (!client.connected())client.stop();
delay(1);
if (client.connect(sh, 80)) {*/
client.println("PUT /api/globalVariables/UID HTTP/1.1");
auth(sh);
Serial.print(cardCode);
Serial.println(" registered");
}
//if (!client.connected())client.stop();
while (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
//while (true);
}
// cleanup and get ready for the next card
bitCount = 0;
facilityCode = 0;
cardCode = 0;
for (i = 0; i < MAX_BITS; i++)
{
databits[i] = 0;
}
delay(10);
net();
delay(10);
server.begin();
}
// Create a client connection
EthernetClient nclient = server.available();
if (nclient) {
Serial.println(F("new client"));
while (nclient.connected()) {
if (nclient.available()) {
/* char c = client.read();
Serial.write(c);
//read char by char HTTP request
if (readString1.length() < 100) {
//store characters to string
readString1 += c;
}*/
readString1 = nclient.readStringUntil('\n');
Serial.println(readString1);
//if HTTP request has ended– 0x0D is Carriage Return \n ASCII
// if (c == 0x0D) {
nclient.println("HTTP/1.1 200 OK"); //send new page
nclient.println("Content-Type: text/html");
nclient.println();
nclient.println(F("<HTML>"));
nclient.println(F("<HEAD>"));
nclient.println(F("<TITLE> Wegand to Home Center Configurator</TITLE>"));
nclient.println(F("</HEAD>"));
nclient.println(F("<BODY style=\"background-color:#F0F0FF; text-align: center;\">"));
nclient.println(F("<br>"));
nclient.println(F("<H1 style=\"color:LimeGreen;\">Wegand<span style=\"color:Teal;\">2</span><span style=\"color:Blue;\">HC</span></H1>"));
// client.println(F("<hr>"));
nclient.println(F("<br>"));
//nclient.println(F("<a style=\"color:SteelBlue;background-color:White;padding: 5px;\" href=\"/?TEST\"\">TEST</a><br /><br />"));
nclient.println(F("<form id=\"txt_form\" name=\"frmText\">"));
nclient.println(F("<H2 style=\"color:Crimson;\"><b>Configurator</b></H2>"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"code\">code : <input type=\"password\" id=\"code\" size=\"4\" maxlength=\"4\" value=\"0000\" /></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"hcip\">Home Center IP : <input type=\"text\" id=\"hcip\" size=\"15\" minlength=\"15\" maxlength=\"15\" value=\""));
if (ship[0] < 10)
{
nclient.print("00");
}
else if (ship[0] < 100)
{
nclient.print("0");
}
nclient.print(ship[0]);
nclient.print(F("."));
if (ship[1] < 10)
{
nclient.print("00");
}
else if (ship[1] < 100)
{
nclient.print("0");
}
nclient.print(ship[1]);
nclient.print(F("."));
if (ship[2] < 10)
{
nclient.print("00");
}
else if (ship[2] < 100)
{
nclient.print("0");
}
nclient.print(ship[2]);
nclient.print(F("."));
if (ship[3] < 10)
{
nclient.print("00");
}
else if (ship[3] < 100)
{
nclient.print("0");
}
nclient.print(ship[3]);
nclient.println(F("\" required></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"sip\">Web Server IP : <input type=\"text\" id=\"sip\" size=\"15\" minlength=\"15\" maxlength=\"15\" value=\""));
if (wsip[0] < 10)
{
nclient.print("00");
}
else if (wsip[0] < 100)
{
nclient.print("0");
}
nclient.print(wsip[0]);
nclient.print(F("."));
if (wsip[1] < 10)
{
nclient.print("00");
}
else if (wsip[1] < 100)
{
nclient.print("0");
}
nclient.print(wsip[1]);
nclient.print(F("."));
if (wsip[2] < 10)
{
nclient.print("00");
}
else if (wsip[2] < 100)
{
nclient.print("0");
}
nclient.print(wsip[2]);
nclient.print(F("."));
if (wsip[3] < 10)
{
nclient.print("00");
}
else if (wsip[3] < 100)
{
nclient.print("0");
}
nclient.print(wsip[3]);
nclient.println(F("\" readonly></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"uid\">User ID : <input type=\"text\" id=\"uid\" size=\"2\" maxlength=\"2\" autocomplete=\"on\" value=\"00\" /></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"sid\">Scene ID : <input type=\"text\" id=\"sid\" size=\"4\" maxlength=\"4\" autocomplete=\"on\" value=\"0000\" /></label><br /><br />"));
nclient.println(F("<a style=\"color:SteelBlue;background-color:White;padding: 5px;\" href=\"\" onclick=\"this.href='/?'+document.getElementById('code').value+document.getElementById('uid').value+document.getElementById('sid').value+document.getElementById('hcip').value+document.getElementById('sip').value\" >EDIT</a>"));
nclient.println(F("</form>"));
nclient.println(F("</BODY>"));
nclient.println(F("</HTML>"));
delay(10);
//stopping client
nclient.stop();
Serial.println(F("client disconnected"));
if (readString1.indexOf("?1729") == 5 && readString1.indexOf("HTTP/1.1") == 47) //checks code
{
Serial.println(F("pwd match"));
// readString1.toCharArray(url, 25);
Serial.println(readString1);
byte ad = readString1.substring(10, 12).toInt();
Serial.println(ad);
if (ad > 0 && ad < 100) {
scene[ad] = readString1.substring(12, 16).toInt();
Serial.println(scene[ad]);
}
else
Serial.println(F("invalid UID"));
byte p = 16;
for (byte i = 0; i < 4; i++) {
ship[i] = readString1.substring(p, p + 3).toInt();
p = p + 4;
}
p--;
for (byte i = 0; i < 4; i++) {
wsip[i] = readString1.substring(p, p + 3).toInt();
p = p + 4;
}
EEPROM.put(10, ship);
EEPROM.put(15, wsip);
EEPROM.put(20, scene);
delay(1500);
EEPROM.get(10, ship);
EEPROM.get(15, wsip);
EEPROM.get(20, scene);
//digitalWrite(5, HIGH);
//delay(1500);
//digitalWrite(5, LOW);
Serial.println(F("Edited"));
}
//clearing string for next read
readString1 = "";
// }
}
}
}
switch (Ethernet.maintain())
{
case 1:
//renewed fail
Serial.println(F("Error: renewed fail"));
break;
case 2:
//renewed success
Serial.println(F("Renewed success"));
//print your local IP address:
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
break;
case 3:
//rebind fail
Serial.println(F("Error: rebind fail"));
break;
case 4:
//rebind success
Serial.println(F("Rebind success"));
//print your local IP address:
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
break;
default:
//nothing happened
break;
}
}
void printBits()
{
// I really hope you can figure out what this function does
Serial.println();
Serial.print("FC = ");
Serial.print(facilityCode);
Serial.print(", CC = ");
Serial.println(cardCode);
}
void net()
{
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
// if (Ethernet.hardwareStatus() == EthernetNoHardware) {
// Serial.println(F("Ethernet shield was not found. Sorry, can't run without hardware. :("));
// } else if (Ethernet.linkStatus() == LinkOFF) {
// Serial.println(F("Ethernet cable is not connected."));
// } else {
// Serial.println(F("No idea why"));
// }
delay(3000);
Ethernet.begin(mac, ip);
if (Ethernet.localIP() != ip)
{
Serial.println(F("Failed to configure Ethernet using static IP"));
for (;;)
;
}
}
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
ip = Ethernet.localIP();
for (byte i = 0; i < 4; i++) {
wsip[i] = ip[i];
}
EEPROM.put(15, wsip);
}
void auth(IPAddress sh)
{
Serial.println(sh);
client.print("Host: ");
client.println(sh);
client.println("Authorization: Basic YmVuc2U6Qmlnc"); //need to insert base 64 user:password
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);
}

Arduino global array not modified when accessed over serial?

I'm working on a home automation system, one part of which includes an Arduino Mega2560 connected via USB to a RaspberryPi 3 Model B. The Arduino receives two short, simple commands over serial from the Pi; the first command sets 'regions' of led lights, and the second sets colors on the regions previously described. Syntax is as follows for both commands, where bracketed items are single bytes, len+off are 3 ascii bytes interpreted as base-10, and r+g+b are 2 ascii bytes each interpreted as hex. The color set command supports a variable number of regions as shown:
Region Set Command
!c[regionId][stripId][len2][len1][len0][off2][off1][off0]\r
Color Set Command
!b[r1][r0][g1][g0][b1][b0][numRegions][regionId0]([regionId1]...)\r
Each command sends positive/negative acknowledgements so you'd think I'd be able to tell what's going wrong, but I get unexpected behavior when I try to set light colors with the second command, however, despite getting acknowledgements as expected. So far, the only reasonable conclusion I can come to is that for the global array regions discards changes and stays zero always. For example, this exchange results in no lights lit (comments are not in the actual exchange)
Pi sends: !c00144000\r // create regionId 0 on stripId 0; length 144 offset 0
Pi recieves: O // positive confirmation?
Pi sends: !b00009910\r // set regionId 0 to color 0x000099 (blue)
Pi recieves: O // positive confirmation, but no lights?
Pi sends: !x\r // invalid command; triggers default in switch
Pi recieves: X // as expected, all lights turn red
Here's the stripped down source for the Arduino:
#include "Arduino.h"
#include "FastLED.h"
#define WAIT while(!Serial.available()) ;;
// Forward Declarations
const int max_strips = 2;
const int max_strip_length = 300;
const int max_leds = max_strips * max_strip_length;
CRGB leds[max_strips][max_strip_length];
const int max_regions = 20;
int regions[max_regions][3];
const int baud_rate = 9600;
unsigned char buffer[64];
unsigned char currentByte = 0;
unsigned char incommingByte;
unsigned char startChar = '!';
unsigned char endChar = '\r';
bool store = false;
// Helper Functions
void set(CRGB c) {
for(int i = 0; i < max_strips; i++) {
for(int j = 0; j < max_strip_length; j++) {
leds[i][j] = c;
}
}
}
void set(int stripId, int length, int offset, CRGB c) {
for(int i = offset; i < offset+length; i++) {
leds[stripId][i] = c;
}
}
void setup() {
Serial.begin(baud_rate);
for(int i = 0; i < max_strips; i++) {
switch(i) {
case 0: {
FastLED.addLeds<WS2812B, 2, GRB>(leds[0], max_strip_length);
} break;
case 1: {
FastLED.addLeds<WS2812B, 3, GRB>(leds[1], max_strip_length);
} break;
}
}
set(CRGB::Black);
}
void loop() {
if(Serial.available() > 0) {
unsigned char incomingByte = Serial.read();
if(incomingByte == startChar) {
currentByte = 0;
store = true;
}
if(store) {
if(incomingByte == endChar) {
buffer[currentByte++] = incomingByte;
store = false;
switch(buffer[1]) {
case 'b': {
int red = (buffer[2] - '0')*16 + (buffer[3] - '0');
int green = (buffer[4] - '0')*16 + (buffer[5] - '0');
int blue = (buffer[6] - '0')*16 + (buffer[7] - '0');
int numRegions = buffer[8] - '0';
for(int i = 0; i < numRegions; i++) {
int regionId = buffer[9+i] - '0';
if(regionId >= max_regions) {
Serial.write('S');
return;
}
// Never sets anything
set(regions[regionId][0], regions[regionId][1], regions[regionId][2], CRGB(red, green, blue));
}
Serial.write('O');
} break;
case 'c': {
int regionId = buffer[2] - '0';
int stripId = buffer[3] - '0';
int length = (buffer[4] - '0')*100 + (buffer[5] - '0')*10 + (buffer[6] -'0');
int offset = (buffer[7] - '0')*100 + (buffer[8] - '0')*10 + (buffer[9] -'0');
if(regionId >= max_regions) {
Serial.write('R');
return;
}
if(stripId >= max_strips) {
Serial.write('S');
return;
}
regions[regionId][0] = stripId; // WE LOSE THESE VALUES??
regions[regionId][1] = length; // ??
regions[regionId][2] = offset; // ??
Serial.write('O');
} break;
default: {
set(CRGB::Red);
Serial.write('X');
} break;
}
currentByte = 0;
}else if(currentByte > 64){
store = false;
currentByte = 0;
} else {
buffer[currentByte++] = incomingByte;
}
}
}
FastLED.show();
}
I'd appreciate any advice as to what I'm missing here, and regardless, thanks for reading this far!
This was occurring because I have a lot of garbage showing up on the serial interface for the Arduino I'm testing on. Slowing the baud rate down to 2400bps resolves the issue on this device. Other Arduinos in the system do fine with much higher serial rates -- I suspect there's a hardware problem with the crystal on this particular Arduino so clock speeds aren't matching up correctly between the two sides of the serial connection.

How to request for two different URL from Arduino one after another?

In the following code segment I am obtaining latitude, longitude, time, date and speed using GPS SKG13BL with Arduino UNO and then send it to the database via GSM module at every 5 secs. And if the speed (stored to s) returned by GPS is greater than 0, then an LED glows else will be low. After this code segment I am performing the database insertion by calling a URL. This works fine and obtains the results as I thought.
Code:
#include <NeoSWSerial.h>
//#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <NMEAGPS.h>
NeoSWSerial GSM(2, 3); // RX, TX: Connect TXD to RX & RXD to TX
static const int RXPin = 8, TXPin = 9; //when looking from antenna of gps , Last TTL pin is to be connected to 8 and second one to 9
AltSoftSerial gpsPort(RXPin, TXPin);
static const uint32_t GPSBaud = 9600;
NMEAGPS gps;
gps_fix fix;
uint8_t fixCount = 0;
char dt[15],tm[15],lati[10],longi[10],rno[13]="kl-05-jb-007";
//int block = 0;
enum _parseState {
PS_DETECT_MSG_TYPE,
PS_IGNORING_COMMAND_ECHO,
PS_HTTPPARA_RESPONSE,
PS_HTTPACTION_TYPE,
PS_HTTPACTION_RESULT,
PS_HTTPACTION_LENGTH,
PS_HTTPREAD_LENGTH,
PS_HTTPREAD_CONTENT
};
enum _actionState {
AS_IDLE,
AS_WAITING_FOR_RESPONSE
};
byte actionState = AS_IDLE;
unsigned long lastActionTime = 0;
int s;
byte parseState = PS_DETECT_MSG_TYPE;
char buffer[160],url[160];
byte pos = 0;
int contentLength = 0;
void resetBuffer() {
memset(buffer, 0, sizeof(buffer));
pos = 0;
}
void sendGSM(const char* msg, int waitMs = 500) {
GSM.println(msg);
while(GSM.available()) {
parseATText(GSM.read());
}
//delay(waitMs);
}
void setup()
{
GSM.begin(9600);
Serial.begin(9600);
gpsPort.begin(GPSBaud);
pinMode(13, OUTPUT); //pin 13 to be connected to positive of LED via a resistor
Serial.println(F("Hinder LOADING....."));
Serial.println(F("obtain gps and store data to database"));
Serial.println(F("Testing by : "));
Serial.println(F("Nikhil,Muthumani and Mathews"));
Serial.println();
sendGSM("AT+SAPBR=3,1,\"APN\",\"vodafone\"");
delay(500);
sendGSM("AT+SAPBR=1,1",3000);
delay(500);
sendGSM("AT+HTTPINIT");
delay(500);
sendGSM("AT+HTTPPARA=\"CID\",1");
delay(500);
}
void loop()
{
unsigned long now = millis();
while (gps.available( gpsPort )) {
fix = gps.read();
//Serial.println(F("b"));
// Once every 5 seconds...
if (++fixCount >= 5) {
//Serial.println(F("a"));
displayInfo();
if(s>0) // Change led state when speed greater than 0 or less than 0
digitalWrite(13, HIGH);
else
digitalWrite(13, LOW);
//send the next report if previous one is finished
if ( actionState == AS_IDLE ) {
sprintf(url, "AT+HTTPPARA=\"URL\",\"http://hinder.000webhostapp.com/HInsert.php?rno=%s&lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",rno,lati,longi,s,dt,tm );
sendGSM(url);
// lastActionTime = now;
parseState = PS_HTTPPARA_RESPONSE; // a new state
actionState = AS_WAITING_FOR_RESPONSE;
fixCount = 0;
}
}
}
/* if ((gps.statistics.chars < 10) && (millis() > 5000)) {
Serial.println( F("No GPS detected: check wiring.") );
while(true);
block=1;
}*/
while(GSM.available()) {
//lastActionTime = now;
parseATText(GSM.read());
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (fix.valid.location) {
dtostrf( fix.latitude(),7,5,lati);
//sprintf(lati,"%d",fix.latitude(),5);
Serial.print(lati);
Serial.print( ',' );
dtostrf( fix.longitude(),8,5,longi);
//sprintf(longi,"%d",fix.longitude(),5);
Serial.print(longi);
} else {
Serial.print(F("INVALID"));
}
Serial.print(F(" Speed: "));
if (fix.valid.speed) {
s=fix.speed_kph();
Serial.print(s);
Serial.print(F(" KMPH "));
} else {
Serial.print(F("INVALID"));
}
// Shift the date/time to local time
NeoGPS::clock_t localSeconds;
NeoGPS::time_t localTime;
if (fix.valid.date && fix.valid.time) {
using namespace NeoGPS; // save a little typing below...
localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
localTime = localSeconds; // convert back to a structure
}
Serial.print(F(" Date : "));
if (fix.valid.date) {
sprintf(dt,"%02d/%02d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
Serial.print(dt);
} else {
Serial.print(F("INVALID"));
}
Serial.print(F(" Time : "));
if (fix.valid.time) {
if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
sprintf(tm,"%02d:%02d:%02d",localTime.hours,localTime.minutes,localTime.seconds);
Serial.print(tm);
//block=1;
} else {
Serial.print(F("INVALID"));
}
Serial.println();
}
void parseATText(byte b) {
buffer[pos++] = b;
if ( pos >= sizeof(buffer) )
resetBuffer(); // just to be safe
/*
// Detailed debugging
Serial.println();
Serial.print("state = ");
Serial.println(state);
Serial.print("b = ");
Serial.println(b);
Serial.print("pos = ");
Serial.println(pos);
Serial.print("buffer = ");
Serial.println(buffer);*/
switch (parseState) {
case PS_HTTPPARA_RESPONSE:
{
parseState = PS_DETECT_MSG_TYPE;
sendGSM("AT+HTTPACTION=0");
/* while(GSM.available()) {
//lastActionTime = now;
parseATText(GSM.read());
}*/
}
break;
case PS_DETECT_MSG_TYPE:
{
if ( b == '\n' )
resetBuffer();
else {
if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
parseState = PS_IGNORING_COMMAND_ECHO;
}
else if ( b == ':' ) {
//Serial.print("Checking message type: ");
//Serial.println(buffer);
if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
Serial.println("Received HTTPACTION");
parseState = PS_HTTPACTION_TYPE;
}
else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
Serial.println("Received HTTPREAD");
parseState = PS_HTTPREAD_LENGTH;
}
resetBuffer();
}
}
}
break;
case PS_IGNORING_COMMAND_ECHO:
{
if ( b == '\n' ) {
Serial.print("Ignoring echo: ");
Serial.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPACTION_TYPE:
{
if ( b == ',' ) {
Serial.print("HTTPACTION type is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_RESULT;
resetBuffer();
}
}
break;
case PS_HTTPACTION_RESULT:
{
if ( b == ',' ) {
Serial.print("HTTPACTION result is ");
Serial.println(buffer);
parseState = PS_HTTPACTION_LENGTH;
resetBuffer();
}
}
break;
case PS_HTTPACTION_LENGTH:
{
if ( b == '\n' ) {
Serial.print("HTTPACTION length is ");
Serial.println(buffer);
// now request content
GSM.print("AT+HTTPREAD=0,");
GSM.println(buffer);
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
}
}
break;
case PS_HTTPREAD_LENGTH:
{
if ( b == '\n' ) {
contentLength = atoi(buffer);
Serial.print("HTTPREAD length is ");
Serial.println(contentLength);
Serial.print("HTTPREAD content: ");
parseState = PS_HTTPREAD_CONTENT;
resetBuffer();
}
}
break;
case PS_HTTPREAD_CONTENT:
{
// for this demo I'm just showing the content bytes in the serial monitor
Serial.write(b);
contentLength--;
if ( contentLength <= 0 ) {
// all content bytes have now been read
parseState = PS_DETECT_MSG_TYPE;
resetBuffer();
Serial.print("\n\n\n");
actionState = AS_IDLE;
}
}
break;
}
}
Now I need a modification in this as, when the speed is greater than 0, along with the glowing of the LED, a variable flag (int flag=0; declared globally) is incremented. And flag is set to 0 when the speed is equal to 0. And if the flag value becomes 2 (i.e when speed is greater than 0 for two consecutive readings) I want to send latitude, longitude, date, time and speed at that instant to another database which is also done by calling a URL (url1). And after that I want to send that to the usual database by calling its URL (url).
I did a modification as follows :
if(s>0) // Change led state when speed greater than 0 or less than 0
{
digitalWrite(13, HIGH);
flag++;
}
else
{
digitalWrite(13, LOW);
flag=0;
}
if(flag==2)
{
sprintf(url1, "AT+HTTPPARA=\"URL\",\"http://speed.000webhostapp.com/HInsert.php?rno=%s&lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",rno,lati,longi,s,dt,tm );
sendGSM(url1);
parseState = PS_HTTPPARA_RESPONSE; // a new state
actionState = AS_WAITING_FOR_RESPONSE;
}
This doesn't obtain result as I thought. Can anyone help me. Is it possible to have flag variable working this way in loop(). Is there a problem with my usage of flag or is it another problem.
It is bit tough to make arduino request for two URLs as we would have to handle two separate request and its responses, either the two request would merge in and wont obtain required result or the code would become large that arduino-uno wont be able to handle.
So i found an easy way for doing that, i.e to request for the second PHP page from the first PHP page (which is requested by arduino itself). The only difference between these two request was that the second one need an extra variable. I passed along with the first request so it was available for making request from first page.
I changed arduino code as follows :
First I modified the portion making the check - just after the displayinfo();, as I mentioned in the question, added a flag bit to it. So it become like this :
if(s>0) // s is speed
{
digitalWrite(13, HIGH); //if speed exceeds limit then LED is set to HIGH
flag++;
}
else
{
digitalWrite(13, LOW);
flag=0;
}
The URL for request from arduino was added with the flag variable too. (For the request for second page).
sprintf(url, "AT+HTTPPARA=\"URL\",\"http://hinder.000webhostapp.com/HInsert.php?flag=%d&rno=%s&lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",flag,rno,lati,longi,s,dt,tm );
In the PHP code I added following lines :
if ( $flag == 2 )
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://masp203.000webhostapp.com/RTO.php?rno=".$rno."&date=".$date."&time=".$time."&speed=".$speed."&street=".$street."" );
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
This worked just the way I wanted it to be.
Hope this helps some one.

Code to run Attiny85 with WS2812 integrated with RGB LED

I am trying to work with this chip:
https://www.adafruit.com/products/1655? ... fgodFpsAow
+
a Attiny85
The code I am using is below, it works fine with an Arduino but not with the Attiny85 (just turns on and stays between 2 colors green and yellow). Any ideas? Thanks!
My ATtiny is set at 8 Mhz with a 800Khz data stream in the neopixel.h library.
Code is below.
#include <Adafruit_NeoPixel.h>
/*
WS2811/Neopixel pattern switcher for ATtiny85 (and Arduino)
Requires Adafruit NeoPixel Library
WS2811 Signal, Digital Pin 4
Button, Digital Pin 0
GPL v3
*/
/*
shin:random pattern selector
*/
// Define
#define NUM_LEDS 1 //60LED per strip
#define DATA_PIN 0 //output pin on ATTiny85
#define BTN_PIN 1 //input pin on ATTiny85
#define BTN_DELAY 250 //add delay for debounce
#define NUM_PATTERNS 12 //patterns avail
#define CTR_THRESH 16
// Init Vars
uint8_t j = 0;
uint8_t pattern=1;
uint8_t buttonState=0;
uint8_t lastPix=0;
uint8_t myPix=0;
uint8_t direction=1;
uint8_t counter=0;
uint8_t colors[3];
uint32_t setColor=0;
unsigned long mark;
// Start Strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
//pinMode(BTN_PIN, INPUT);
randomSeed(BTN_PIN);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// if button pressed, advance, set mark
//chkBtn(digitalRead(BTN_PIN));
int rand = random(1,13);//1to12
// if pattern greater than #pattern reset
//if (pattern > NUM_PATTERNS) { pattern = 1; }
if (rand > NUM_PATTERNS) { pattern = 1; }
// choose a pattern
//pickPattern(pattern);
pickPattern(rand);
// set direction
if (direction == 1) { j++; } else { j--; }
if (j > 254) { direction = 0; }
if (j < 1) { direction = 1; }
}
/* pick a pattern */
void pickPattern(uint8_t var) {
switch (var) {
case 1:
// scanner, color and delay - RGB
scanner(strip.Color(255,0,0),50);
scanner(strip.Color(200,0,100),50);
scanner(strip.Color(64,0,200),50);
break;
case 2:
// color wipe random RGB
colorWipe(strip.Color(random(255), random(255), random(255)),50);
break;
case 3:
// color wave - Hue/Sat/Bright
// hue low (0-359), high (0-359),rate,extra delay
wavey(200,240,0.06,0);
break;
case 4:
// rainbow firefly, 1px at random
colorFirefly(60);
counter++;
break;
case 5:
// rainbow solid
rainbow(10);
counter++;
break;
case 6:
// bounce in and out
// tail len, counter, delay
bounceInOut(4,counter,20);
counter++;
break;
case 7:
// color wipe from center
colorWipeCenter(strip.Color(255,0,0),100);
colorWipeCenter(strip.Color(255,64,0),100);
break;
case 8:
// solid color
colorFast(strip.Color(255,0,0),0);
break;
case 9:
// fade even or odd
// 0-359 Hue value, even/odd, delay
fadeEveOdd(200,0,20);
fadeEveOdd(300,1,20);
break;
case 10:
// show rainbow
rainbowCycle(10);
break;
case 11:
// show rainbow
theaterChaseRainbow(50);
break;
case 12:
rainbowCycle2(20);
break;
}
}
/* check button state */
boolean chkBtn(int buttonState) {
if (buttonState == HIGH && (millis() - mark) > BTN_DELAY) {
j = 0;
mark = millis();
pattern++;
return true;
}
else { return false; }
}
void colorFirefly(int wait) {
if(myPix != lastPix) {
if(counter<CTR_THRESH) {
float colorV = sin((6.28/30)*(float)(counter)) *255;
HSVtoRGB((359/CTR_THRESH)*counter, 255, colorV, colors);
strip.setPixelColor(myPix, colors[0], colors[1], colors[2]);
strip.show();
delay(wait);
} else {
lastPix=myPix;
counter=0;
colorFast(0,0);
}
} else {
myPix=random(0,strip.numPixels());
}
}
// Fill the dots one after the other with a color
// Modified from Neopixel sketch to break on button press
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// color wipe from center
void colorWipeCenter(uint32_t c, uint8_t wait) {
uint8_t mid=strip.numPixels()/2;
strip.setPixelColor(mid,c);
for(uint16_t i=0; i<=strip.numPixels()/2; i++) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.setPixelColor(mid+i, c);
strip.setPixelColor(mid-i, c);
strip.show();
delay(wait);
}
}
// fast version
void colorFast(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
delay(wait);
}
// Rainbow Cycle, modified from Neopixel sketch to break on button press
void rainbowCycle(uint8_t wait) {
uint16_t i;
// for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
// }
}
void rainbow(uint8_t wait) {
uint16_t i;
//for(j=0; j<256; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
delay(wait);
// }
}
// scanner
void scanner(uint32_t c,uint8_t wait) {
for(int i=0; i< strip.numPixels(); i++) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
colorFast(0,0);
strip.setPixelColor(i,c);
strip.show();
delay(wait);
}
for(int i=strip.numPixels(); i>0; i--) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
colorFast(0,0);
strip.setPixelColor(i,c);
strip.show();
delay(wait);
}
}
// scanner to midpoint
void bounceInOut(uint8_t num, uint8_t start,uint8_t wait) {
colorFast(0,0);
uint8_t color=200;
for(int q=0; q < num; q++) {
if(strip.numPixels()-start >= 0 && start < NUM_LEDS) {
strip.setPixelColor(start+q, strip.Color(0,color,0));
strip.setPixelColor(strip.numPixels()-start-q, strip.Color(0,color,0));
}
color=round(color/2.0);
strip.show();
delay(wait);
}
if(counter > strip.numPixels()) { counter=0; }
}
void fadeEveOdd(int c1,byte rem,uint8_t wait) {
for(int j=0; j < CTR_THRESH; j++) {
for(int i=0; i< strip.numPixels(); i++) {
if(i % 2== rem) {
HSVtoRGB(c1,255,(255/CTR_THRESH)*j,colors);
strip.setPixelColor(i,colors[0],colors[1],colors[2]);
}
}
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.show();
delay(wait);
}
for(int j=CTR_THRESH; j >= 0; j--) {
for(int i=0; i< strip.numPixels(); i++) {
if(i % 2== rem) {
HSVtoRGB(c1,255,(255/CTR_THRESH)*j,colors);
strip.setPixelColor(i,colors[0],colors[1],colors[2]);
}
}
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.show();
delay(wait);
}
}
// twinkle random number of pixels
void twinkleRand(int num,uint32_t c,uint32_t bg,int wait) {
// set background
colorFast(bg,0);
// for each num
for (int i=0; i<num; i++) {
strip.setPixelColor(random(strip.numPixels()),c);
}
strip.show();
delay(wait);
}
// sine wave, low (0-359),high (0-359), rate of change, wait
void wavey(int low,int high,float rt,uint8_t wait) {
float in,out;
int diff=high-low;
int step = diff/strip.numPixels();
for (in = 0; in < 6.283; in = in + rt) {
for(int i=0; i< strip.numPixels(); i++) {
out=sin(in+i*(6.283/strip.numPixels())) * diff + low;
HSVtoRGB(out,255,255,colors);
strip.setPixelColor(i,colors[0],colors[1],colors[2]);
}
strip.show();
delay(wait);
if(chkBtn(digitalRead(BTN_PIN))) { break; }
}
}
// sine wave, intensity
void waveIntensity(float rt,uint8_t wait) {
float in,level;
for (in = 0; in < 6.283; in = in + rt) {
for(int i=0; i< strip.numPixels(); i++) {
// sine wave, 3 offset waves make a rainbow!
level = sin(i+in) * 127 + 128;
// set color level
strip.setPixelColor(i,(int)level,0,0);
}
strip.show();
delay(wait);
if(chkBtn(digitalRead(BTN_PIN))) { break; }
}
}
// helpers
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
// HSV to RGB colors
// hue: 0-359, sat: 0-255, val (lightness): 0-255
// adapted from http://funkboxing.com/wordpress/?p=1366
void HSVtoRGB(int hue, int sat, int val, uint8_t * colors) {
int r, g, b, base;
if (sat == 0) { // Achromatic color (gray).
colors[0] = val;
colors[1] = val;
colors[2] = val;
} else {
base = ((255 - sat) * val) >> 8;
switch (hue / 60) {
case 0:
colors[0] = val;
colors[1] = (((val - base) * hue) / 60) + base;
colors[2] = base;
break;
case 1:
colors[0] = (((val - base) * (60 - (hue % 60))) / 60) + base;
colors[1] = val;
colors[2] = base;
break;
case 2:
colors[0] = base;
colors[1] = val;
colors[2] = (((val - base) * (hue % 60)) / 60) + base;
break;
case 3:
colors[0] = base;
colors[1] = (((val - base) * (60 - (hue % 60))) / 60) + base;
colors[2] = val;
break;
case 4:
colors[0] = (((val - base) * (hue % 60)) / 60) + base;
colors[1] = base;
colors[2] = val;
break;
case 5:
colors[0] = val;
colors[1] = base;
colors[2] = (((val - base) * (60 - (hue % 60))) / 60) + base;
break;
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle2(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
Hi all thank you very much for the help. I've ended up fixing it. See below:
"
The memory was okay. I think you were right that the clock speeds are different for the arduino and the attiny.
I ended up using the libraries found here:
https://github.com/cpldcpu/light_ws2812
Then I loaded the AVR example. I had to copy the ws2812 library into my actual code as the Arduino library wasn't able to find the library. After doing that it finally worked.
"
Thanks for all the help!
Dave
Another solution is to include:
ifdef AVR
include <avr/power.h>
endif
and change the setup:
#if defined (__AVR_ATtiny45__)
if (F_CPU == 8000000) clock_prescale_set(clock_div_1);
#endif
Code below:
// This is a demonstration on how to use an input device to trigger changes on your neo pixels.
// You should wire a momentary push button to connect from ground to a digital IO pin. When you
// press the button it will change to a new pixel animation. Note that you need to press the
// button once to start the first animation!
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define BUTTON_PIN 0 // Digital IO pin connected to the button. This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily. On a high -> low
// transition the button press logic will execute.
#define PIXEL_PIN 4 // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 8
// Parameter 1 = number of pixels in strip, neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream, correct for neopixel stick
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
bool oldState = HIGH;
int showType = 0;
void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny45__)
if (F_CPU == 8000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
pinMode(BUTTON_PIN, INPUT_PULLUP);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Get current button state.
bool newState = digitalRead(BUTTON_PIN);
// Check if state changed from high to low (button press).
if (newState == LOW && oldState == HIGH) {
// Short delay to debounce button.
delay(20);
// Check if button is still low after debounce.
newState = digitalRead(BUTTON_PIN);
if (newState == LOW) {
showType++;
if (showType > 9)
showType=0;
startShow(showType);
}
}
// Set the last button state to the old state.
oldState = newState;
}
void startShow(int i) {
switch(i){
case 0: colorWipe(strip.Color(0, 0, 0), 50); // Black/off
break;
case 1: colorWipe(strip.Color(255, 0, 0), 50); // Red
break;
case 2: colorWipe(strip.Color(0, 255, 0), 50); // Green
break;
case 3: colorWipe(strip.Color(0, 0, 255), 50); // Blue
break;
case 4: theaterChase(strip.Color(127, 127, 127), 50); // White
break;
case 5: theaterChase(strip.Color(127, 0, 0), 50); // Red
break;
case 6: theaterChase(strip.Color( 0, 0, 127), 50); // Blue
break;
case 7: rainbow(20);
break;
case 8: rainbowCycle(20);
break;
case 9: theaterChaseRainbow(50);
break;
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
Troubleshooting these boards can be very challenging. My initial thought is that you might be running out of memory on the ATtiny. Have you tried a minimal amount of code with only one animation function just for testing?
Also it looks like there is a lot more activity on this topic over at the Electrical Engineering Stack Exchange:
https://electronics.stackexchange.com/questions/24269/checking-memory-footprint-in-arduino
https://electronics.stackexchange.com/questions/74872/memory-management-problems-with-attiny85

Resources