UDP error on beginPacket - c

I got an error on my arduino when I send a UDP-package any ip.
There 2 problems when I try to send a packet to _targetIp:
When called from loop() then udpSender.endPacket() freeze forever (on second call, first call was fine)
When called from setup() then udpSender.beginPacket(...) returns 0
Code:
IPAddress _targetIp(192, 168, 59, 250);
int _sendPort = 4321;
EthernetUDP _udpSender;
(...)
void sendUpd(int pinIndex, int value)
{
// if I wrote something like this:
// udpSender.beginPacket(_udpSender.remoteIP(), _sendPort)
// then is all fine
if (_udpSender.beginPacket(_targetIp, _sendPort) != 1)
{
Serial.println("socket error!");
return;
}
_udpSender.write(pinIndex);
_udpSender.write("=");
_udpSender.write(value);
int sendState = _udpSender.endPacket(); // hang forever when called from "loop()"
if ( sendState != 1 )
{
// enters with 0 as "sendState" when called from "setup()"
Serial.print("send error: ");
Serial.println( sendState );
}
}
Can anybody explain that for me?

Founded solutions:
Not the call _updSender.endPacket() freezes. The code to read a specific digital in (digitalRead(52)) causes the strange reaction.
I dont know how, but the arduino check if the host alive. If the host not reachable, the _udpSender.endPacket() returns 0.
Explantation:
Resolving the IP to an MAC adress fails. So the error does not came from UDP (layer 4 OSI). The error happend in data-link-layer (=2) and explains point 2.

Related

Arduino microphone/AMB decoder combination gets interrupted

Microphone readout gets randomly interrupted
I have a microphone hooked up to my Arduino on a Serial hardware port 2.
https://sigrok.org/wiki/Colead_SL-5868P
I receive data from the microphone by sending 0x20 to it. The following functions read out it's data.
FlushMic1 is a function to flush out the Serial2 buffer, so we can read out the correct data from the buffer.
String getMic1()
{
String valueMic;
if(flushedMic1())
{
Serial2.write(0x20);
while (Serial2.available() <= 10){;}
valueMic = "";
for (int i = 0; i < 10; i++)
{
int data = Serial2.read();
valueMic += String(data);
}
}
return valueMic;
}
bool flushedMic1()
{
bool returnBool = false;
while(Serial2.available())
{
Serial2.read();
returnBool = true;
}
return returnBool;
}
On another port I have a transponder loop connected, to measure passing transponders.
If a transponder passes it sends char to the Serial Hardware port 1. It can be detected if it includes a '#'.
bool isTransponderPassing()
{
char data = Serial1.read();
if (data == '#')
{
return true;
}
return false;
}
Running the getMic1() function in a loop works perfectly fine. If the : if(isTransponderPassing()) is used in the in main loop I sometimes get the correct data, sometimes false data, when I receive false data, the entire program gets interrupted, which propably fills the buffer with 16's and that's why we receive 16's.
Who knows where my program can get stuck?
void setup()
{
// Starts the serial monitor
Serial.begin(2400);
// Starts Serial monitor of AMB decoder
Serial1.begin(9600);
// Starts Serial monitor of microphone 1
Serial2.begin(2400);
}
void loop()
{
Serial.println(Serial2.available());
Serial.println(Serial1.available());
if(isTransponderPassing())
{
Serial.println(getMic1());
}
}
I fixed the issue, because I wasn't aware Serial.readString() in getMic1() has a delay of 1 second. So I should just read the documentation better next time.
So everyone, Serial.readString() has a delay of 1 second, hope this saves time for others!
Use Serial.readStringUntil(char ofChoice) instead, this reads the buffer into a String, but quits when it has reached the given char.
Buffer = "Hello world";
// Serial.readString() does:
delay(1000);
return Buffer;
result : "Hello world"
// Serial.readStringUntil("o") does:
return BufferUntilChar("o")
result : "Hello wo"

Ethernet connect fails with LWIP in mbed os

I'm using an mbed enabled board for development, I need to run an Ethernet application on it.
I tried to create a connection by using the following code:
network = new EthernetInterface();
network->connect();
// Show the network address
const char *ip = network->get_ip_address();
printf("IP address is: %s\n", ip ? ip : "No IP");
Normally it should work, But it fails in the LWIPInteraface class's bringup API at osSemaphoreAcquire, returning a timeout error.
if (!netif_is_link_up(&netif)) {
if (blocking){
if (osSemaphoreAcquire(linked, 15000) != osOK){
if (ppp){
(void) ppp_lwip_disconnect(hw);
}
return NSAPI_ERROR_NO_CONNECTION;
}
}
}
Any reason why I might be getting a timeout from osSemaphoreAcquire?
I tried increasing the timeout too but in vain.
If someone could help me with it, would be appreciated.
Thanks in advance.

Strange behaviour of Win32_NetworkAdapterConfiguration::EnableDHCP?

My application has ablities to turn network adaptors of or enable them for either DHCP or static configuration. IP configuration is done via WMI Win32_NetworkApapterConfiguration class and disabling/enabling adapters is done via SetupApi for some reasons. Starting at the point where the adapter was enabled, I noticed following (Windows 7 SP1, 32bit):
EnableDHCP method return with error 84 (IP not enabled). So I thought I need to wait that property the "IpEnabled" becomes true and polled it every second - but it always returned false (BTW: I monitored the value using WMIC and could see that it has actually became true).
Next - in order to avoid and inifinite loop - I changed my "poll 'IpEnabled == true' loop" to jump out after 10 trials, and do the remaining stuff. And see: EnableDHCP succeeded (ret == 0), and also IpEnabled suddely became true.
EDIT
Situation 1:
int ret;
// ...
// Returns error 84
ret = wmiExecMethod(clsName, "EnableDHCP", true, objPath);
// ...
Situation 2:
int ret;
// ...
// Will never get out of this
while (!wmiGetBool(pWMIObj, "IPEnabled"))
{
printf("Interface.IpEnabled=False\n");
Sleep(1000);
}
// ...
ret = wmiExecMethod(clsName, "EnableDHCP", true, objPath);
Situation 3:
int count = 10;
int ret;
// ...
// Will occur until count becomes 0
while (wmiGetBool(pWMIObj, "IPEnabled") && count--)
{
printf("Interface.IpEnabled=False - remaining trials: %d\n", count);
Sleep(1000);
}
// ...
// After this "delay", EnableDHCP returns 0 (SUCCESS)
ret = wmiExecMethod(clsName, "EnableDHCP", true, objPath);
// wmiGetBool(pWMIObj, "IPEnabled") now returns true too...
Do you have any ideas what is going wrong here? Thanks in before for help.
Best regards
Willi K.
The "real" problem behind this is that the Win32_NetworkApapterConfiguration::EnableDHCP method fails if the interface is not connected to a network (offline). The only way I found to configure the interface for DHCP is to modify the registry....

serial.println(String) prints "#" instead of the string

i'm just trying to recieve a string using a serial and to send this string back. So when i send a string to an arduino over a serial the arduino should automaticly send this string back.
i created this code:
String test;
void setup(){
Serial.begin(9600);
Serial.setTimeout(2);
test = "null";
}
void loop(){
if(Serial.available()){
test = Serial.readString();
}
Serial.println(test);
}
I guess it is not that difficult to understand. However now the arduino will always print a "#" instead of the variable test. My connected serial device is a bluetooth modul. (hc-06)
What did i do wrong?
Thank you!
(i also ran this code in the arduino emulator 123D Circuits. There it worked just fine)
You need change your code. Move println into if statement.
Try increase timeout interval, 2ms is not enough, good value (at 9600) lies above 10ms. Theoretically timeout should be at least 3.5 characters long and for current speed this equals ~0,4 ms. But in practice higher values are used.
String test;
void setup(){
Serial.begin(9600);
Serial.setTimeout(10);// or more
test = "null";
}
void loop(){
if(Serial.available()){
test = Serial.readString();
Serial.println(test);// moved into if
}
}
Update: Another simple solution to return characters back looks like:
void loop(){
if(Serial.available()) Serial.write(Serial.read());
}
Update 2: Had similar issue with BLE module HM10 (clone, not official). It was sending about 15 dummy bytes prior to any array. And i didn't solve it. But if weired bytes always the same you can make a simple trick using String.remove():
if(Serial.available()){
test = Serial.readString();
test.remove(0,5);
// test.remove - add code to remove last character
Serial.println(test);
}
Also try another terminal.

Serial.print only once Arduino

I have a light sensor that prints the value of its input to the Serial monitor. It's pretty much a trip wire but when an object is in its way, it prints the value every 1 millisecond. If I add a delay it won;t trigger the second sensor until the delay is done. How would I get it to only print once, without any disturbance or interference with the other sensors?
void loop() {
if (analogRead(sensor1) == 0) {
timer.start ();
tStop = false;
//Serial.println (timer.elapsed());
Serial.println ("Start Time = 0");
}
This is quite an interesting problem, in the normal world of computers we would solve this via threading. However as you are running without an OS we have to do one of two things, implement coroutines (fake threading without an OS) or use asynchronous code and interrupts.
My understanding is that you print something when an object first comes into the way of your sensor, as the arduino uno as opposed to the due is not easy to implement coroutines on we shall try the interrupt route.
First you will likely be interested in this library http://playground.arduino.cc/Code/Timer1
It allows you to add an interrupt service routine to run on a timer. Use the attachInterrupt(function, period) function in the library for this.
In your interrupt service routine you will want to check the sensor, set a variable to say how long ago since it was last triggered and print the message if appropriate. This means your main loop is completely free to run other code and will not block your other sensors.
For example:
void TimFun()
{
static int LastRead;
if(LastRead && (0 == analogRead(sensor1))
{
Serial.println("SensorTrip");
}
LastRead = analogRead(sensor1);
}
void loop()
{
// Do other stuff here
}
void setup()
{
Timer1.initialize(100000);
Timer1.attachInterrupt(TimFun);
// Rest of setup Here
}
I managed to make an int before the void setup and then used a while loop. with in the if statement.
int i = 1;
if (analogRead(sensor1) == 0) {
timer.start ();
tStop = false;
while (i == 1) {
Serial.println ("Start Time = 0");
i++;
}
}
You probably should use an if instead of a while loop that will never execute more than once.
bool tripped = false;
void setup(){
//setup stuff here
}
void loop() {
if ( analogRead(sensor1) == 0 )
{
timer.start ();
tStop = false;
if ( tripped == false )
{
Serial.println ("Start Time = 0");
tripped = true;
}
}
}

Resources