Hey guys,
I’ve got some trouble with the TCPClient, being that I can’t use several client.print()'s without a delay of at least 500ms between each.
My code (the important bits are within VirtualShield.cpp):
vshield-2.ino
#include "application.h"
#include "VirtualShield.h"
#define SERVER "abcde.myfritz.net"
#define PORT 80
bool flashmode = false;
int loops = 0;
VShield led = VShield(SERVER, PORT, "led"); //Server, Port, and type of virtual object
void setup() {
pinMode(D4, INPUT);
//flash mode - it works, though there's propably a nicer way
if(digitalRead(D4) == LOW){
flashmode = true;
pinMode(D7, OUTPUT);
digitalWrite(D7, HIGH);
}
else{
led.begin("red", 3); //color and quantity
}
}
void loop() {
if(!flashmode){
led.flick(1); //on -> off, off -> on
led.on(2);
led.off(3);
loops++;
led.looped(loops); //debugging, how many loops so far?
delay(1000);
}
}
VirtualShield.cpp
#include "VirtualShield.h"
VShield::VShield(const char* _host, int _port, String _type){
host = _host;
port = _port;
type = _type;
}
bool VShield::begin(int arg1, int arg2){ //connect to server and send information about the virtual object
if(type = "lcd"){
arg_type1 = ",cols:";
arg_type2 = ",rows:";
}
else return false;
bool res = client.connect(host, port);
if(res){
client.println();
client.println();
client.println("Connected.");
delay(delayT);
client.print("type:");
delay(delayT);
client.print(type);
delay(delayT);
client.print(",cmd:begin");
delay(delayT);
client.print(arg_type1);
delay(delayT);
client.print(arg1);
delay(delayT);
client.print(arg_type2);
delay(delayT);
client.print(arg2);
delay(delayT);
client.println("$"); // = end of command
delay(delayT);
}
return res;
}
bool VShield::begin(String arg1, int arg2){
if (type = "led"){
arg_type1 = ",color:";
arg_type2 = ",quantity:";
}
else return false;
bool res = client.connect(host, port);
if(res){
client.println();
client.println();
client.println("Connected.");
delay(delayT);
client.print("type:");
delay(delayT);
client.print(type);
delay(delayT);
client.print(",cmd:begin");
delay(delayT);
client.print(arg_type1);
delay(delayT);
client.print(arg1);
delay(delayT);
client.print(arg_type2);
delay(delayT);
client.print(arg2);
delay(delayT);
client.println("$"); // = end of command
delay(delayT);
}
return res;
}
void VShield::print(String msg){
if(type = "lcd"){
client.print("type:");
delay(delayT);
client.print(type);
delay(delayT);
client.print(",cmd:print,msg:");
delay(delayT);
client.print(msg);
delay(delayT);
client.print("$"); // = end of command
delay(delayT);
}
}
void VShield::flick(int led){
if(type = "led"){
client.print("type:");
delay(delayT);
client.print(type);
delay(delayT);
client.print(",cmd:flick");
delay(delayT);
client.print(",led:");
delay(delayT);
client.print(led);
delay(delayT);
client.print("$"); // = end of command
delay(delayT);
}
}
void VShield::on(int led){
if(type = "led"){
client.print("type:");
delay(delayT);
client.print(type);
delay(delayT);
client.print(",cmd:on");
delay(delayT);
client.print(",led:");
delay(delayT);
client.print(led);
delay(delayT);
client.print("$"); // = end of command
delay(delayT);
}
}
void VShield::off(int led){
if(type = "led"){
client.print("type:");
delay(delayT);
client.print(type);
delay(delayT);
client.print(",cmd:off");
delay(delayT);
client.print(",led:");
delay(delayT);
client.print(led);
delay(delayT);
client.print("$"); // = end of command
delay(delayT);
}
}
void VShield::looped(int loops){
client.print(" -- looped -- loops: ");
client.println(loops);
}
VirtualShield.h
#include "application.h"
class VShield {
public:
//Server name + port, specifying type of object
VShield(const char* _host, int _port, String type);
//'begin' for different objects + client.connect
bool begin(int arg1, int arg2); //lcd (for now)
bool begin(String arg1, int arg2); //led (for now)
//for lcd only
void print(String msg);
//for led only
void flick(int led);
void on(int led);
void off(int led);
//meant for debugging
void looped(int loops);
private:
TCPClient client;
const char* host;
int port;
String type;
int delayT = 500;
String arg_type1;
String arg_type2;
};
Output:
Connected.
type:led,cmd:begin,color:red,quantity:3$
type:led,cmd:flick,led:1$
type:led,cmd:on,led:2$
type:led,cmd:off,led:3$
-- looped -- loops: 1
type:led,cmd:flick,led:1$
type:led,cmd:on,led:2$
type:led,cmd:off,led:3$
-- looped -- loops: 2
type:led,cmd:flick,led:1$
type:led,cmd:on,led:2$
type:led,cmd:off,led:3$
-- looped -- loops: 3
type:led,cmd:flick,led:1$
type:led,cmd:on,led:2$
type:led,cmd:off,led:3$
-- looped -- loops: 4
[...]
My first try was to have only one string containing all the information and send it with one single client.print(cmd). However, the core would send only part of the string (something around 10 chars), then hang and eventually blink red, SOS 1 (hard fault). I then saw someone use delays of 10ms between each client.print, so I went and printed every part of the command separately with said delay. But it wasn’t until I increased the delay to 500ms until the Core behaved as expected. Funny enough it is precisely 500ms. If I go beneath that (even 499ms), the Core will hang again.
The idea is to have a virtual shield (as you might have already guessed from the library name credits for the idea to http://www.1sheeld.com/). So I would much like it to be as ‘realtime’ as possible.
What am I doing wrong?