I have a sketch that reads switch positions and sends a message on the net when they change using an Ethernet Shield. I am trying to add a capability to temporarily update some parameters at startup using the USB port and the Serial interface. The problem I run into is that any serial input calls seem to block. I can output using Serial.print and Serial.println but Serial.Available and Serial.peek both see to block waiting for input which may not always be available.
I am currently using an Arduino Uno with a Ethernet Shield from Seeed Studio. The circuit boards are installed in a plastic project box . The only hardware added to this project are the connectors use to connect external switches. Before I added the software to read configuration information from the computer the software worked properly. After adding the Serial code it stopped working. If I add debug information (printing to the terminal) I can see that the Application on the Arduino is waiting / blocking at the Serial.available line. No errors are reported.
I did not see any setup options available to set blocking to non-blocking mode for the serial class.
Any help would be greatly appreciated.
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mLocalMacAddr[] = {0xD6, 0xAD, 0xBE, 0x00, 0x00, 0x02 };
IPAddress localIp(10, 99, 99, 99);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char mSendMsgBuf[40]; // a string to send back
char mReadBuf[40];
int mReadIndex = 0;
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
#define ACTIVE_PINS 4
int mPinBuf[ACTIVE_PINS];
int mActivePins = ACTIVE_PINS;
unsigned short mRemotePortNum = 4000;
IPAddress mRemoteAddress(10, 99, 99, 99);
void setup()
{
// start the Ethernet and UDP:
Ethernet.begin(mLocalMacAddr, localIp);
Udp.begin(localPort);
Serial.begin(115200);
// clear all pins in buffer and emable the pullup resistor
// the switches toggle to ground
for (int index = 0; index < ACTIVE_PINS; index++)
{
mPinBuf[index] = 1;
pinMode(index, INPUT_PULLUP);
}
}
void loop()
{
if (Serial.available() > 0)
{
char inChar = Serial.read();
if (inChar != '\n')
{
mReadBuf[mReadIndex++] = inChar;
}
else
{
mReadBuf[mReadIndex] = '\0';
mReadIndex = 0;
}
}
for (int index = 0; index < mActivePins; index++)
{
int pinVal = digitalRead(index);
if (pinVal != mPinBuf[index])
{
mPinBuf[index] = pinVal;
#ifdef DEBUG
Serial.print("Pin ");
Serial.print(index);
Serial.print(": ");
Serial.println(pinVal);
#endif // DEBUG
if (index == 2)
{
if (pinVal == 1)
{
sprintf(mSendMsgBuf, "<PTT>ON</PTT>", index);
}
else
{
sprintf(mSendMsgBuf, "<PTT>OFF</PTT>", index);
}
}
else if (index == 3)
{
if (pinVal == 1)
{
sprintf(mSendMsgBuf, "<STT>ON</STT>", index);
}
else
{
sprintf(mSendMsgBuf, "<STT>OFF</STT>", index);
}
}
#ifdef DEBUG
Serial.println(mSendMsgBuf);
#endif // DEBUG
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(mRemoteAddress, mRemotePortNum);
Udp.write(mSendMsgBuf);
Udp.endPacket();
}
}
delay(10);
}
Your code reads lines of data from the serial port but does nothing when a complete line is entered.
You don't do any bounds checking so that if a line of more than 39 characters is entered, your code will clobber something off the end of the array, leading to unpredictable behaviour such as "blocking at the Serial.available line".