Arduino programming help

Frunple

Active Member
I have two programs that run fine on their own. I'd like to combine them and run them both on one Arduino but I can't figure it out.
 
The first one displays the status of my blinds, I shortened it to one blind for posting here.
 

int z1w1switchstate;

z1w1reading = digitalRead(z1w1Pin);

// If the switch changed, due to bounce or pressing...
if (z1w1reading != z1w1previous)
{
// reset the debouncing timer
time = millis();
}

if ((millis() - time) > debounce)
{
// whatever the switch is at, its been there for a long time
// so lets settle on it!
z1w1switchstate = z1w1reading;

// Now invert the output
if (z1w1switchstate == HIGH)
z1w1State = LOW;
else
z1w1State = HIGH;
}

// print the results to the serial monitor:
if (z1w1State != lastz1w1State)
{
if (z1w1State == HIGH)
{
Serial.print("Z1W11\r\n" );
}
else
{
Serial.print("Z1W10\r\n" );
}
}

digitalWrite(z1w1Outpin, z1w1State);

// Save the last reading so we keep a running tally
z1w1previous = z1w1reading;
lastz1w1State = z1w1State;
}

The second is something I just started to play with. It pings my phone ip to determine when I'm home.
 

#include <SPI.h>
#include <Ethernet.h>
#include <ICMPPing.h>

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; // mac address for ethernet shield
byte ip[] = {10,12,8,60}; // ip address for ethernet shield
IPAddress pingAddr(10,12,8,26); // ip address to ping

SOCKET pingSocket = 0;

char buffer [256];
ICMPPing ping(pingSocket, (uint16_t)random(0, 255));

void setup()
{
// start Ethernet
Ethernet.begin(mac, ip);
Serial.begin(9600);
}

void loop()
{
ICMPEchoReply echoReply = ping(pingAddr, 4);
if (echoReply.status == SUCCESS)
{
Serial.print("Scott\r\n");
startfresh();
}
else
{
delay(1000);
}
}

void startfresh()
{
ICMPEchoReply echoReply = ping(pingAddr, 4);
if (echoReply.status == SUCCESS)
{
delay(300000);
startfresh();
}
else
{
loop();
}
}

They both then interface with Elve to do what I want.
 
The problem is the delays. They shut down all operations for the full delay.
What I've come up with so far is below, it I call the pingme() function I lock out of the loop(), I know this but I just pasted it in for place holding for now.
 

#include <SPI.h>
#include <Ethernet.h>
#include <ICMPPing.h>

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; // mac address for ethernet shield
byte ip[] = {10,12,8,60}; // ip address for ethernet shield
IPAddress pingAddr(10,12,8,26); // ip address to ping

SOCKET pingSocket = 0;

char buffer [256];
ICMPPing ping(pingSocket, (uint16_t)random(0, 255));

int z1w1Pin = A0; // the number of the input pin
int z1w1Outpin = 22; // the number of the output pin
int z1w1State = LOW; // the current state of the output pin
int lastz1w1State; // the previous state of the output pin
int z1w1reading; // the current reading from the input pin
int z1w1previous = HIGH; // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 50; // the debounce time, increase if the output flickers

void setup()
{
Ethernet.begin(mac, ip);
pinMode(z1w1Pin, INPUT_PULLUP);
pinMode(z1w1Outpin, OUTPUT);
Serial.begin(9600);
}

void loop()
{
int z1w1switchstate;

z1w1reading = digitalRead(z1w1Pin);

// If the switch changed, due to bounce or pressing...
if (z1w1reading != z1w1previous)
{
// reset the debouncing timer
time = millis();
}

if ((millis() - time) > debounce)
{
// whatever the switch is at, its been there for a long time
// so lets settle on it!
z1w1switchstate = z1w1reading;

// Now invert the output
if (z1w1switchstate == HIGH)
z1w1State = LOW;
else
z1w1State = HIGH;
}

// print the results to the serial monitor:
if (z1w1State != lastz1w1State)
{
if (z1w1State == HIGH)
{
Serial.print("Z1W11\r\n" );
}
else
{
Serial.print("Z1W10\r\n" );
}
}

digitalWrite(z1w1Outpin, z1w1State);

// Save the last reading so we keep a running tally
z1w1previous = z1w1reading;
lastz1w1State = z1w1State;
}

void pingme()
{
ICMPEchoReply echoReply = ping(pingAddr, 4);
if (echoReply.status == SUCCESS)
{
Serial.print("Scott\r\n");
startfresh();
}
else
{
delay(1000);
}
}

void startfresh()
{
ICMPEchoReply echoReply = ping(pingAddr, 4);
if (echoReply.status == SUCCESS)
{
delay(300000);
startfresh();
}
else
{
loop();
}
}

Any help is appreciated... it's all new to me!
 
Instead of using delay in several places you might try using counters instead. Then at the end of the loop, after the code that does the work, you would have a single delay statement, perhaps delay(100).
 
The idea is you run through all of your code periodically. Then the counters can be used to count how many times you have looped through the code and thus implement "delays".
 
Yeah, I get the idea... just can't seem to implement it. Everything I do, does one or the other, then both after one is true.
Can't get it to run the ping until successful, but have the blind status always running.
 
Frunple said:
Yeah, I get the idea... just can't seem to implement it. Everything I do, does one or the other, then both after one is true.
Can't get it to run the ping until successful, but have the blind status always running.
 
I cannot find the docs for the library with the the ping command but I will guess that it is not returning until it finishes.
 
But in the code you posted you have pingme() and startfresh().
 
1. I don't see where you are using these
2. startfresh() is calling loop() which I don't think is workable
 
 
Try just including the call to ping() with no other processing right before the delay(xxx) at the end of the void() loop.
 
Frederick C. Wilt said:
I cannot find the docs for the library with the the ping command but I will guess that it is not returning until it finishes.
 
But in the code you posted you have pingme() and startfresh().
 
1. I don't see where you are using these
2. startfresh() is calling loop() which I don't think is workable
 
 
Try just including the call to ping() with no other processing right before the delay(xxx) at the end of the void() loop.
https://github.com/BlakeFoster/Arduino-Ping

1. I'm not in that posted code. Like I said above, If I call the pingme(), it locks me out of the loop(). I just posted all the code I have for reference.
 
2. It actually works great if I just use the second code posted (just the ping stuff).
 
I tried the ping() call, it pings correctly (as the code should I mean) but it won't monitor the blinds unless the ping sees my phone. Then if I remove my phone, no blinds again.
 
I've been trying something different, posted below, but still getting the same. Only works if my phone is "seen".
Thanks for looking into it, I might actually learn something!! Then again, I can just go buy an Uno and run each program on a separate Arduino... but where's the fun in that??
 
Code:
#include <SPI.h>
#include <Ethernet.h>
#include <ICMPPing.h>
 
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; // mac address for ethernet shield
byte ip[] = {10,12,8,60}; // ip address for ethernet shield
IPAddress pingAddr(10,12,8,26); // ip address to ping
 
SOCKET pingSocket = 0;
 
char buffer [256];
ICMPPing ping(pingSocket, (uint16_t)random(0, 255));

int z1w1Pin = A0;         // the number of the input pin
int z1w1Outpin = 22;       // the number of the output pin
int z1w1State = LOW;      // the current state of the output pin
int lastz1w1State;		// the previous state of the output pin
int z1w1reading;           // the current reading from the input pin
int z1w1previous = HIGH;    // the previous reading from the input pin
int pingstatus = LOW;

 
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 50;   // the debounce time, increase if the output flickers
long interval = 1000;
long previousMillis = 0; 

void setup()
{
	Ethernet.begin(mac, ip);
	Serial.begin(9600);
	pinMode(z1w1Pin, INPUT_PULLUP);
	pinMode(z1w1Outpin, OUTPUT);
}

void loop()
{
	blindstatus();
	if (pingstatus != HIGH)
	{
		pingme();
	}
}

void blindstatus()
{
	int z1w1switchstate;
	
	z1w1reading = digitalRead(z1w1Pin);
	// If the switch changed, due to bounce or pressing...
	if (z1w1reading != z1w1previous)
	{
		// reset the debouncing timer
		time = millis();
	}
	
	if ((millis() - time) > debounce)
	{
		// whatever the switch is at, its been there for a long time
		// so lets settle on it!
		z1w1switchstate = z1w1reading;
		
		// Now invert the output
		if (z1w1switchstate == HIGH)
			z1w1State = LOW;
		else
			z1w1State = HIGH;
	}
	
	// print the results to the serial monitor:
	if (z1w1State != lastz1w1State)
	{
		if (z1w1State == HIGH)
		{
			Serial.print("Z1W11\r\n" );
		}
		else
		{
			Serial.print("Z1W10\r\n" );
		}
	}
	
	digitalWrite(z1w1Outpin, z1w1State);
	
	// Save the last reading so we keep a running tally
	z1w1previous = z1w1reading;
	lastz1w1State = z1w1State;
}

void pingme()
{
	ICMPEchoReply echoReply = ping(pingAddr, 4);
	if (echoReply.status == SUCCESS)
	{
		Serial.print("Scott\r\n");
		pingstatus = HIGH;
	}
	else
	{
		Serial.print("no\r\n");
		pingstatus = LOW;
	}
}

void pingmetimeout()
{

}
 
I think that if you put some debug statements before and after just a call to ping() you will find that when ping() cannot connect to the desired device it takes a long time to return.
 
Try it and see.
 
Using delay function causes problems whenever you try to do more than one thing at once so should generally be avoided. Your first code uses millis() instead which is much preferred - it doesn't prevent other things from happening.

Here is more on that:
http://playground.arduino.cc/Code/AvoidDelay

The serial print statements can take time and cause problems too. If that's the issue then making the strings shorter will help.
 
Back
Top