I have a MCP9700A temp sensor connected to my spark.
I have my spark setup as a tcp server which will report the temperature to the clients every 10s.
Hardware is simple. temp sensor connected to 3V3*, A0 and gnd. Powered using USB wallwart.
Problem 1:
When a client is connected that client should get the message “Hello”. On Connection only. i have run this several times and at some point it starts to send a stream of “Hello”’ 's. why?
Problem 2:
I guessing that my temp sensor is sensing correctly but i can’t seem to output the correct value constantly.
as you can see on the screen capture i get a weird character sometimes.
is this to do with my analogRead or my server.print?
i do get from time to time a fast flashing cyan. or a red (hard fault).
i have also from time to time lost connection to my spark aswell.
// telnet defaults to port 23
TCPServer server = TCPServer(23);
TCPClient client;
void setup()
{
// start listening for clients
server.begin();
// Make sure your Serial Terminal app is closed before powering your Core
Serial.begin(9600);
// Now open your Serial Terminal, and hit any key to continue!
while(!Serial.available()) SPARK_WLAN_Loop();
Serial.println(Network.localIP());
Serial.println(Network.subnetMask());
Serial.println(Network.gatewayIP());
Serial.println(Network.SSID());
}
void loop()
{
if (client.connected()) {
// echo all available bytes back to the client
while (client.available()) {
server.write(client.read());
}
} else {
// if no client is yet connected, check for a new connection
client = server.available();
}
}
Ok, lets get this thing apart.
client.connected() means another computer has connect to the core
client.available() means data has been send from the client
Using the sample above shows the right behaviour. If client is connected and client data is received the code send them back. If no data is received but the client is still connected, do nothing. If the client has disconnected, check for new connection.
Now your code
Line 28-31: If a client has connected you set a LED and wait 1 second => why?
Line 33: You send to the client "Hello!"
Line 35-47: If the client has send some data, you send for every single byte to the client the temp.
Line 49: And you wait for every single byte 9.5sec.
Then start all over at Line 26 (client still connected, sending some data)
What you should do
Do NOT use delay()
use millis() to detect interval times. If millies()>millisbefore+9500 => send temp data => then save current millis() in millisbefore
Imagine your code runs as fast as hell, and no delays are allowed. How would you write it then?
Please do not send Code as graphic, it is very hard do read and to show you how to correct it.
Line 28-31 set LED to indicate to me that it has connected and the second is to allow time for it to establish a stable connection. I have read some postings indicating that repeated postings or requests in quick succession can cause the red led sos. i don’t see the red anymore but i do see a blue breathing led from time to time.
Line 35-47 if the client has sent some data. while the client is sending data send the temp over and over every 9.5 secs. if the client stops sending data then start over at line 26.
Thanks for the tips i will make the changes to millis(). i hope this helps with the crashing but i don’t think this will help the odd Character that i get on the print of temp.
Should i be putting a “millis wait” before manipulating the temp value after the reading of A0 to allow the AtoD time to process?
Also in the Example you posted there is a “while(!Serial.available()) SPARK_WLAN_Loop();” what is this?
// telnet defaults to port 23
TCPServer server = TCPServer(23);
TCPClient client;
void loop()
{
if (client.connected())
{
digitalWrite(led, HIGH);
delay(1000);
server.write("Hello!");
while (client.available())
{
// echo all available bytes back to the clients
server.write(client.read());
// Read Sensor value
temp = analogRead(Sensor)*3.3/4095.0;
delay(500);
temp = temp - 0.5;
temp = temp * 100;
// Send Temperature to Clients
server.println(temp);
delay(9500);
}
}
else
{
digitalWrite(led, LOW);
// if no client is yet connected, check for a new connection
client = server.available();
}
}
so i did a little more troubleshooting.
i stripped out a lot and what I’m running into is the communication fails after 2 writes.
i have tried the same code on 2 different spark cores and they both fail at the same place.
the response i get when it connects is “Hello1Hello2” and that’s it. the core then displays a red led (sos) hard fault error.
here’s the code i’m running for this test.
// telnet defaults to port 23
TCPServer server = TCPServer(23);
TCPClient client;
float temp;
int led = D7;
int Sensor = A0;
unsigned long millisBefore = millis();
// telnet defaults to port 23
TCPServer server = TCPServer(23);
TCPClient client;
int led = D7;
void setup() {
//PIN Inputs
pinMode(Sensor, INPUT);
pinMode(led, OUTPUT);
// start listening for clients
server.begin();
Serial1.begin(115200);
Serial1.println(WiFi.localIP());
Serial1.println(WiFi.subnetMask());
Serial1.println(WiFi.gatewayIP());
Serial1.println(WiFi.SSID());
}
void loop() {
SPARK_WLAN_Loop(); // keep connection with the cloud
if (client.connected()) {
Serial1.print("c"); // the beacon that we have a valid connection here
digitalWrite(led, HIGH);
server.write("Hello"); // say Hello to the client
delay(50); // wait some short time to help debugging
server.write(13);
server.write(10); // new line please
while (client.available()) {
Serial1.print("a"); // ooh, the client has send some data
server.write(client.read()); // just send back whats received
delay(50); // debugging helper again
}
} else {
digitalWrite(led, LOW);
// if no client is yet connected, check for a new connection
client = server.available();
}
}
It sends endless Hello and write back received data too.
Case 1: If I start the telnet session it will send Hello forever. As a reference, the code also sends beacon data to Serial1, my debug connection.
Case 2: typing some characters to the core is handled right, the debugger shows the character ‘a’.
Case 3: If I keep the finger on the keyboard sending many character in series, after some seconds, the debugger does not send any beacons and after a fiew seconds the pulsing red led shows a mature failure. The core seems to recover from that state, but ends in blinking cyon after some 2 minutes (no new telnet session to the core since then). It recovers again and connection is possible.
You are right, there must be something deeper then our code can handle. There is no buffer handling. I do not know if there is any overflow handling on TCP side at all.
It can be informative to include sending some millis() as debugging info. In my project I noticed that many hickups have similar duration (most frequent: 60 seconds, runner-up: 20 seconds), indicating some low level time-out.
Additionally you could add pinging your router (gateway). In my case the user code often regains control after a time-out, but pinging the gateway (once or multiple times) fails, whereas before the disturbance it succeeded…
I think you might have built a packet amplifier since for every character you get from the client, you are sending a one character packet back. I know that the example code does this, but it is just an example not built for a particular purpose.
Have you tried gathering the client.read() bytes into an array and then writing the whole array back via the server?
You could also try looking at the return values from server.write() which should be positive on success.