ESP8266 Access Point Mode - Intermittent when connecting - c++

I'm using an ESP8266 in access point mode to send it some data (wifi credentials) from a mobile app via HTTP. The access point init code is very simple:
IPAddress apIP(10, 10, 10, 1);
IPAddress subnet(255,255,255,0);
WiFi.softAPConfig(apIP, apIP, subnet);
WiFi.softAP(ACCESS_POINT_NAME); // No password requird
What I find is that sometimes the mobile phone connects to the ESP's network seamlessly, and other times seriously struggles (rejects the connection, or takes > 3 mins to connect).
Questions are:
Are there issues with this code that could make a connection to the ESP by a client temperamental (sometimes fine, other times not)? Like should I change the WiFi channel from 1? Are the static IP/Subnet mask creating issues?
Is the issue likely hardware related - i.e. sometimes the client gets a good wifi signal from the ESP, sometimes not?

If anyone else faces this, I found a large performance improvement from doing the following:
Removing DNS
Reseting the WiFi config
Explicitly setting the module to AP mode - this is referenced by this Github issue comment. This seems to be the primary driver of improvement.
So the code is now:
// Set up WiFi mode [Improve AP stability - no dual STA mode]
ESP.eraseConfig();
WiFi.mode(WIFI_AP);
IPAddress apIP(10, 10, 10, 1);
IPAddress subnet(255,255,255,0);
WiFi.softAPConfig(apIP, apIP, subnet);
WiFi.softAP(ACCESS_POINT_NAME); // No password
WiFi.printDiag(Serial);
The reasoning is that while in STA mode, the ESP may channel hop (depending on the environment), and the AP gets pulled with it. So any client connected before the channel hop will have to reconnect.

Related

Winsock sendto returns error 10049 (WSAEADDRNOTAVAIL) for broadcast address after network adapter is disabled or physically disconnected

I am working on a p2p application and to make testing simple, I am currently using udp broadcast for the peer discovery in my local network. Each peer binds one udp socket to port 29292 of the ip address of each local network interface (discovered via GetAdaptersInfo) and each socket periodically sends a packet to the broadcast address of its network interface/local address. The sockets are set to allow port reuse (via setsockopt SO_REUSEADDR), which enables me to run multiple peers on the same local machine without any conflicts. In this case there is only a single peer on the entire network though.
This all works perfectly fine (tested with 2 peers on 1 machine and 2 peers on 2 machines) UNTIL a network interface is disconnected. When deactivacting the network adapter of either my wifi or an USB-to-LAN adapter in the windows dialog, or just plugging the usb cable of the adapter, the next call to sendto will fail with return code 10049. It doesn't matter if the other adapter is still connected, or was at the beginning, it will fail. The only thing that doesn't make it fail is deactivating wifi through the fancy win10 dialog through the taskbar, but that isn't really a surprise because that doesn't deactivate or remove the adapter itself.
I initially thought that this makes sense because when the nic is gone, how should the system route the packet. But: The fact that the packet can't reach its target has absolutely nothing to do with the address itsself being invalid (which is what the error means), so I suspect I am missing something here. I was looking for any information I could use to detect this case and distinguish it from simply trying to sendto INADDR_ANY, but I couldn't find anything. I started to log every bit of information which I suspected could have changed, but its all the same on a successfull sendto and the one that crashes (retrieved via getsockopt):
250 16.24746[886] [debug|debug] local address: 192.168.178.35
251 16.24812[886] [debug|debug] no remote address
252 16.25333[886] [debug|debug] type: SOCK_DGRAM
253 16.25457[886] [debug|debug] protocol: IPPROTO_UDP
254 16.25673[886] [debug|debug] broadcast: 1, dontroute: 0, max_msg_size: 65507, rcv_buffer: 65536, rcv_timeout: 0, reuse_addr: 1, snd_buffer: 65536, sdn_timeout: 0
255 16.25806[886] [debug|debug] Last WSA error on socket was WSA Error Code 0: The operation completed successfully.
256 16.25916[886] [debug|debug] target address windows formatted: 192.168.178.255
257 16.25976[886] [debug|debug] target address 192.168.178.255:29292
258 16.26138[886] [debug|assert] ASSERT FAILED at D:\Workspaces\spaced\source\platform\win32_platform.cpp:4141: sendto failed with (unhandled) WSA Error Code 10049: The requested address is not valid in its context.
The nic that got removed is this one:
1.07254[0] [platform|info] Discovered Network Interface "Realtek USB GbE Family Controller" with IP 192.168.178.35 and Subnet 255.255.255.0
And this is the code that does the sending (dlog_socket_information_and_last_wsaerror generates all the output that is gathered using getsockopt):
void send_slice_over_udp_socket(Socket_Handle handle, Slice<d_byte> buffer, u32 remote_ip, u16 remote_port){
PROFILE_FUNCTION();
auto socket = (UDP_Socket*) sockets[handle.handle];
ASSERT_VALID_UDP_SOCKET(socket);
dlog_socket_information_and_last_wsaerror(socket);
if(socket->is_dummy)
return;
if(buffer.size == 0)
return;
DASSERT(socket->state == Socket_State::created);
u64 bytes_left = buffer.size;
sockaddr_in target_socket_address = create_socket_address(remote_ip, remote_port);
#pragma warning(push)
#pragma warning(disable: 4996)
dlog("target address windows formatted: %s", inet_ntoa(target_socket_address.sin_addr));
#pragma warning(pop)
unsigned char* parts = (unsigned char*)&remote_ip;
dlog("target address %hhu.%hhu.%hhu.%hhu:%hu", parts[3], parts[2], parts[1], parts[0], remote_port);
int sent_bytes = sendto(socket->handle, (char*) buffer.data, bytes_left > (u64) INT32_MAX ? INT32_MAX : (int) bytes_left, 0, (sockaddr*)&target_socket_address, sizeof(target_socket_address));
if(sent_bytes == SOCKET_ERROR){
#define LOG_WARNING(message) log_nonreproducible(message, Category::platform_network, Severity::warning, socket->handle); return;
switch(WSAGetLastError()){
//#TODO handle all (more? I guess many should just be asserted since they should never happen) cases
case WSAEHOSTUNREACH: LOG_WARNING("socket %lld, send failed: The remote host can't be reached at this time.");
case WSAECONNRESET: LOG_WARNING("socket %lld, send failed: Multiple UDP packet deliveries failed. According to documentation we should close the socket. Not sure if this makes sense, this is a UDP port after all. Closing the socket wont change anything, right?");
case WSAENETUNREACH: LOG_WARNING("socket %lld, send failed: the network cannot be reached from this host at this time.");
case WSAETIMEDOUT: LOG_WARNING("socket %lld, send failed: The connection has been dropped, because of a network failure or because the system on the other end went down without notice.");
case WSAEADDRNOTAVAIL:
case WSAENETRESET:
case WSAEACCES:
case WSAEWOULDBLOCK: //can this even happen on a udp port? I expect this to be fire-and-forget-style.
case WSAEMSGSIZE:
case WSANOTINITIALISED:
case WSAENETDOWN:
case WSAEINVAL:
case WSAEINTR:
case WSAEINPROGRESS:
case WSAEFAULT:
case WSAENOBUFS:
case WSAENOTCONN:
case WSAENOTSOCK:
case WSAEOPNOTSUPP:
case WSAESHUTDOWN:
case WSAECONNABORTED:
case WSAEAFNOSUPPORT:
case WSAEDESTADDRREQ:
ASSERT(false, tprint_last_wsa_error_as_formatted_message("sendto failed with (unhandled) ")); break;
default: ASSERT(false, tprint_last_wsa_error_as_formatted_message("sendto failed with (undocumented) ")); //The switch case above should have been exhaustive. This is a bug. We either forgot a case, or maybe the docs were lying? (That happened to me on android. Fun times. Well. Not really.)
}
#undef LOG_WARNING
}
DASSERT(sent_bytes >= 0);
total_bytes_sent += (u64) sent_bytes;
bytes_left -= (u64) sent_bytes;
DASSERT(bytes_left == 0);
}
The code that generates the address from ip and port looks like this:
sockaddr_in create_socket_address(u32 ip, u16 port){
sockaddr_in address_info;
address_info.sin_family = AF_INET;
address_info.sin_port = htons(port);
address_info.sin_addr.s_addr = htonl(ip);
memset(address_info.sin_zero, 0, 8);
return address_info;
}
The error seems to be a little flaky. It reproduces 100% of the time until it decides not to anymore. After a restart its usually back.
I am looking for a solution to handle this case correctly. I could of course just re-do the network interface discovery when the error occurs, because I "know" that I don't give any broken IPs to sendto, but that would just be a heuristic. I want to solve the actual problem.
I also don't quite understand when error 10049 is supposed to fire exactly anyway. Is it just if I pass an ipv6 address to a ipv4 socket, or send to 0.0.0.0? There is no flat out "illegal" ipv4 address after all, just ones that don't make sense from context.
If you know what I am missing here, please let me know!
This is a issue people have been facing up for a while , and people suggested to read the documentation provided by Microsoft on the following issue .
"Btw , I don't know whether they are the same issues or not but the error thrown back the code are same, that's why I have attached a link for the same!!"
https://learn.microsoft.com/en-us/answers/questions/537493/binding-winsock-shortly-after-boot-results-in-erro.html
I found a solution (workaround?)
I used NotifyAddrChange to receive changes to the NICs and thought it for some reason didn't trigger when I disabled the NIC. Turns out it does, I'm just stupid and stopped debugging too early: There was a bug in the code that diffs the results from GetAdaptersInfo to the last known state to figure out the differences, so the application missed the NIC disconnecting. Now that it observes the disconnect, it can kill the sockets before they try to send on the disabled NIC, thus preventing the error from happening. This is not really a solution though, since there is a race condition here (NIC gets disabled before send and after check for changes), so I'll still have to handle error 10049.
The bug was this:
My expectation was that, when I disable a NIC, iterating over all existing NICs would show the disabled NIC as disabled. That is not what happens. What happens is that the NIC is just not in the list of existing NICs anymore, even though the windows dialog will still show it (as disabled). That is somewhat suprising to me but not all that unreasonable I guess.
Before I had these checks to detect changes in the NICs:
Did the NIC exist before, was enabled and is now disabled -> disable notification
Did the NIC exist before, was disabled and is now enabled -> enable notification
Did the NIC not exist before, is not enabled -> enable notification
And the fix was adding a fourth one:
Is there an existing NIC that was not in the list of NICs anymore -> disable notification
I'm still not 100% happy that there is the possibility of getting a somewhat ambiguous error on a race condition, but I might call it a day here.

rtsp-sink(RTSPStreamer) DirectShow.Net filter based RTSP server causes high latency in complete network and even slowdown the network speed by 90%

Ref: I have a RTSP media server that sends video via TCP streaming.I am using rtsp-sink(RTSPStreamer) DirectShow.Net filter based RTSP server which is developed in C++.Where as The Wrapper app is developed using C#.
The problem i am facing is the moment RTSP server start streaming,it affects the system level internet connection & drops internet connection speed by 90 percent.
I wanted to get your input on how it would be possible? (if at all).Because it impacts on system level internet connection not the very app level.
For Example:- My normal internet connection speed is 25 mbps. It suddenly drops to 2 mbps , whenever the RTSP streaming started in the app's server tab.
Sometimes even disables the internet connection in the system(Computer) where the app is running.
I'm asking you because I consider you an expert so please bear with me on this "maybe wild" question and thanks ahead.
...of all the things I've lost, I miss my mind the most.
Code Snippet of RTSPSender.CPP
//////////////////////////////////////////////////////
// CStreamingServer
//////////////////////////////////////////////////////
UsageEnvironment* CStreamingServer::s_pUsageEnvironment = NULL;
CHAR CStreamingServer::s_szDefaultBroadCastIP[] = "239.255.42.42";
//////////////////////////////////////////////////////
CStreamingServer::CStreamingServer(HANDLE hQuit)
: BasicTaskScheduler(10000)
, m_hQuit(hQuit)
, m_Streams(NAME("Streams"))
, m_bStarting(FALSE)
, m_bSessionReady(FALSE)
, m_pszURL(NULL)
, m_rtBufferingTime(UNITS * 2)
{
s_pUsageEnvironment = BasicUsageEnvironment::createNew(*this);
rtspServer = NULL;
strcpy_s(m_szAddress,"");
strcpy_s(m_szStreamName,"stream");
strcpy_s(m_szInfo,"media");
strcpy_s(m_szDescription,"Session streamed by \"RTSP Streamer DirectShow Filter\"");
m_nRTPPort = 6666;
m_nRTSPPort = 8554;
m_nTTL = 1;
m_bIsSSM = FALSE;
}
Edited:WireShark logs:
WireShark logs at the time of RTSP streaming started

Lwip on mbed-os 5 doesn't make a proper ethernet connection

My goal is to send UDP packets from the microcontroller (nucleo board) to the PC - as simple as that. Update: I reached the goal successfully. I'll explain here how I did it, and the problems I stumbled upon initially. Many thanks to the StackOverflow community and people on LinkedIn ARM group to help me out!
1. SYSTEM OVERVIEW
My system is as follows:
1.1 Microcontroller side
Nucleo_F767ZI board with STM32F767ZI microcontroller. This board has an ethernet connector.
Mbed-OS 5 operating system.
lwip library (wich is part from the Mbed-OS 5 operating system).
1.2 PC side 🖳
Windows 10, 64-bit.
Free ethernet port (internet is through WiFi, that's why this ethernet port is unused).
Wireshark to see if the microcontroller actually sends out UDP packets. Interpretation of them will be done later on in Python. First I want to see packets in Wireshark.
1.3 Connections
Initially I connected the nucleo board directly to my computer, without a router or switch involved. Such a setup requires "static IP configuration". I would configure the PC to have IP address "192.168.1.10" and the microcontroller to have "192.168.1.20". I know this can work, because I've done it before with a PIC microcontroller.
But this situation is a little different. I got a little operating system running on the microcontroller: mbed-os v5. This operating system makes use of Lwip (Light-weight ip stack). Although it should be possible to configure a "static IP address", the software currently doesn't support it. More information can be found here: https://developer.mbed.org/questions/74145/EthernetInterfaceinit-mbed-os-5x-not-wor/. Because there is no way to configure a static IP address on the microcontroller, you need a DHCP server. The microcontroller connects to the network without an IP address, and broadcasts a packet with the question: "What IP address should I use on this network?". If the microcontroller doesn't get an answer, it will broadcast the question a few times, and eventually give up.
If there is a DHCP server connected to the network, it will receive the question and hand over a free IP address. So that is what you need. There are several ways to provide such a DHCP server:
Install a DHCP server on your Windows PC. This is the only way to keep switches and routers out of the picture. The nucleo board is connected directly to the PC. When the microcontroller broadcasts the question, the Windows PC hands over an IP address. After that, communication can start.
Throw a Raspberry PI into the game. The Raspberry PI should run a DHCP server. Connect the three devices (Windows PC, Raspberry PI and Nucleo board) to a switch.
Buy a simple router. Home routers have a DHCP server built-in. Connect the Windows PC and the Nucleo board to the LAN ports of this router.
I decided to go for the third option. The following figure shows the connections to my Netgear R7000 router:
2. ROUTER SETUP
The DHCP server inside the router will hand out IP addresses to all devices that connect to it. My router will hand out the IP address "192.168.1.2" to the first device, "192.168.1.3" to the second, and so forth all the way up to "192.168.1.254". But that's a bit problematic. How can the PC and the microcontroller know each others IP addresses? Perhaps there are more clever solutions, but I've figured out the following approach.
Each DHCP server has a table with "reserved IP addresses". In this table, you can add devices and assign a static IP address to them. So whenever that device asks for an IP address, the DHCP server takes a look in the table and hands over the one you've configured. But how does the DHCP server recognizes a device? It can recognize a device by its MAC-address. Every device has a globally unique MAC-address of 6 bytes.
This is how I've added my Windows PC and my microcontroller to the table:
STEP 1: Connect the computer to one of the LAN ports of the router. Switch the router on.
STEP 2: Make sure that all WiFi on your computer is disconnected. I've experienced lots of issues with this. (*)
STEP 3: Open a browser, and surf to "192.168.1.1". This is my routers home page. It could be different for your router.
STEP 4: Login (my routers default login is "admin" for the username and "password" for the password)
STEP 5: Add the Windows PC and the microcontroller board to the table. You have to look up their MAC-addresses first (**):
2.1 Disconnect all WiFi (*)
This should be a simple step, but Windows makes it hard. Windows can be quite stubborn and reconnect automatically to WiFi networks around, even if you've unchecked the connect automatically box! To force Windows to listen to you, you can use the cmd terminal. Open a cmd terminal with admin privileges. Next, type the following command to see all your WiFi profiles:
> netsh wlan show profiles
Apply the following command to those WiFi profiles that your PC is stubbornly connecting to:
> netsh wlan set profileparameter name="someWifiName" connectionmode=manual
Now you can disconnect from that WiFi network, and Windows won't reconnect automatically anymore.
2.2 Find the MAC address of your PC (**)
This is how I found the MAC-address of my computer. Keep in mind that a computer can have several MAC-addresses. The one for your ethernet port will be different to the one for your wireless connection! Type ipconfig /all in the Windows cmd terminal. I got the following output:
# Note: this is the correct item!
# --------------------------------
Ethernet adapter Local Area Connection:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Intel(R) Ethernet Connection (2) I219-LM
Physical Address. . . . . . . . . : C8-xx-xx-xx-xx-01 # Replaced some numbers by x for security :-)
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Make sure you're looking at the correct item in the list of connections. Ethernet adapter Local Area Connection is the correct one for my computer, because the network card description fits what is expected: Intel(R) Ethernet Connection (2) I219-LM. Before, I was looking at another item in the list, labelled Ethernet adapter Ethernet:
# Note: this is the wrong item!
# ------------------------------
Ethernet adapter Ethernet:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : TAP-Windows Adapter V9
Physical Address. . . . . . . . . : 00-xx-xx-xx-xx-F7
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Mr. Joel C (see his answer below) notified me that the network card from that item is TAP-Windows Adapter V9. Apparently that is a virtual network card. That made me lose a lot of time. Thank you Mr. Joel C for helping me out!
Please make also sure that DHCP Enabled and Autoconfiguration Enabled are turned on!
2.3 Find the MAC address of your Nucleo board (**)
I found the MAC-address of my Nucleo board with the following code:
#include "lwip-interface/EthernetInterface.h"
//1. Make an ethernet object
EthernetInterface eth;
//2. Try to connect
eth.connect(); // <- This line will not work now,
// but at least it will help you to find out your
// own MAC-address.
//3. Print the MAC-address
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
The print output I got over my serial port is (some numbers I replaced by x for security):
Controller MAC Address is: 00:xx:xx:xx:xx:40
3. MICROCONTROLLER CODE
This is the code that runs on the microcontroller. My main.cpp file is inspired on the code found on the Mbed-os forum at https://forums.mbed.com/t/udp-receive-with-nucleo-f767zi/1806.
#include <string>
using std::string;
#include "mbed.h"
#include "lwip-interface/EthernetInterface.h"
static Serial logger(USBTX, USBRX);
static DigitalOut led1(LED1);
// IP addresses
#define IP_COMPUTER "192.168.1.10" // Make sure these IP addresses correspond to the
#define IP_NUCLEO "192.168.1.20" // table of 'reserved IP addresses' you have setup in
// your routers DHCP server!
// Ethernet settings
const int PORT_T = 50000;
const int PORT_R = 50001;
EthernetInterface eth;
static void udp_tx_thread_func();
static void udp_rx_thread_func();
static Thread udp_tx_thread;
static Thread udp_rx_thread;
int main()
{
// 1. Initialize the serial logger
logger.baud(115200);
logger.printf("\r\n\r\nApplication started\r\n");
// 2. Initialize and start the UDP connection
eth.connect();
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
logger.printf("Controller IP Address is: %s\r\n", eth.get_ip_address());
Thread::wait(200);
udp_tx_thread.start(udp_tx_thread_func);
udp_rx_thread.start(udp_rx_thread_func);
while (true)
{
led1 = !led1;
Thread::wait(500);
}
}
//------------------ Ethernet --------------------------------------------------
static void udp_tx_thread_func()
{
UDPSocket socket(&eth);
SocketAddress sock_addr(IP_COMPUTER, PORT_T);
static uint32_t out_buffer[3];
while(true)
{
Thread::wait(100);
// Send 3 values of 32-bit each
out_buffer[0] = 150500;
out_buffer[1] = 255300;
out_buffer[2] = 54;
int ret = socket.sendto(sock_addr, &out_buffer[0], 12); // 3 values of 32-bit equals 12 bytes
//logger.printf("sendto return: %d\r\n", ret);
}
}
static void udp_rx_thread_func()
{
UDPSocket socket(&eth);
SocketAddress sock_addr;
int bind = socket.bind(PORT_R);
logger.printf("bind return: %d\n", bind);
char buffer[256];
while(true)
{
//logger.printf("\nWait for packet...\n");
int n = socket.recvfrom(&sock_addr, buffer, sizeof(buffer));
buffer[n] = '\0';
//logger.printf("Packet from \"%s\": %s\n", sock_addr.get_ip_address(), buffer);
Thread::wait(500);
}
}
4. RESULTS
4.1 Wireshark results
In Wireshark I can see the UDP packets flowing in on the Local Area Connection! Huray!
4.2 Python code
The python code to catch the UDP packets looks like this:
import sys
import os
import socket
import dataprocessing.datastruct as datastruct
def main():
# 1. Configure the IP address
# -----------------------------
myAddr = ('192.168.1.10', 50000)
# 2. Create a UDP socket
# -----------------------
sock = None
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(1.5)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(myAddr)
print('UDPsock #: ' + str(sock.getsockname()))
sys.stdout.flush()
except Exception as e:
print('Could not bind to the UDP socket.')
print(e)
sys.stdout.flush()
while (true):
try:
data, address = sock.recvfrom(256) # buffer size is 256 bytes
bytedata = bytearray(data)
# Each 32-bit number is cut in 8-bit pieces. Bring them back together.
value_01 = bytedata[0] + 256*bytedata[1] + 65536*bytedata[2] + 16777216*bytedata[3]
value_02 = bytedata[4] + 256*bytedata[5] + 65536*bytedata[6] + 16777216*bytedata[7]
value_03 = bytedata[8] + 256*bytedata[9] + 65536*bytedata[10] + 16777216*bytedata[11]
print("Value 01: %d", value_01)
print("Value 02: %d", value_02)
print("Value 03: %d", value_03)
except socket.error as err:
print(err)
if __name__== '__main__':
print("")
print("Start UDP catcher")
print("-----------------")
main()
5. LET WIFI AND ETHERNET COEXIST
The UDP packets from the microcontroller flow in on your ethernet port (passing along the router). Meanwhile you might want to connect to some WiFi network for internet access. The problem is that any browser will try to get access through your ethernet port - ignoring the WiFi.
The solution is to make your browsers FIRST attempt to use the WiFi to reach an IP address, next attempt through the Ethernet port. This is done with the "Interface metric" in the Control Panel. Increase this number slightly:
The connection you have labelled Ethernet is actually a TAP connection (eg. a virtual ethernet card). Your actual ethernet connection is labelled Local Area Connection; that is the connection you will need to be configuring and watching with Wireshark, etc.
As to everything else Mbed-OS related, I personally have not dealt with it.

Why Serial Communications from Arduino stops after some time

I'm building a growbox/terrarium with arduino uno as the temperature controller. Simple sketch for arduino: if DS18B20 sensor giv less than 25'C than turn on relay, which the heating cable is connected to. Loop 30s, every time Serial.print(temperature) to the PC, where I'm collecting data and make timelapse photos. ---> Here is the problem.
After some time (from 15 min up to 4 hours). Serial communication with PC stops. When I'm trying to upload a new sketch to arduino I got an error msg:
avrdude: ser_open(): can't set com-state for "\.\COM3"
I need to unplug and plug in again USB cable (or turn it off and on in Windows Device Manager), also restart Python app that is collecting data. (Very unsatisfactory fix).
So my questions are:
1. Why?
2. How to fix it?
3. Or how to make some workaround, for example reset COM port from code (desirably python2.7)
PS. Example of what I'm doing and how it works(and do not works) here: Life of pepper
PS2. My goal is to make controllable habitate for plants, where I can see behaviours differs depending on the temp, day-duration, light-intensity, humidity.
Please help me :-) .
ARDUINO UNO SKETCH
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the A
rduino
#define ONE_WIRE_BUS 2
#define PIN_HEATING 6
float temperatura = 30.0;
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
pinMode(PIN_HEATING, OUTPUT);
}
void loop(void)
{
delay(30000);
if(temperatura<25.0){
digitalWrite(PIN_HEATING, HIGH);
}
else{
digitalWrite(PIN_HEATING, LOW);
}
sensors.requestTemperatures(); // Send the command to get temperatures
// After we got the temperatures, we can print them here.
// We use the function ByIndex, and as an example get the temperature from the first sensor only.
temperatura = sensors.getTempCByIndex(0);
Serial.print("#");
Serial.print(temperatura);
}
PYTHON2.7 RECEIVING PART
import serial #pySerial
ser = serial.Serial()
ser.port = "COM3"
ser.open()
data = ser.read_all().split("#")
datasize = len(data)
if datasize>1:
temp = data[datasize-1]
tempstr = " / " + str(temp) + "'C"
else:
tempstr=" / ----- "
I've experienced a similar problem in the past where the serial port would become unresponsive. The solution in my case wasn't very intuitive but worked nonetheless. Here's what might help you too:
Make sure the USB port you're using to connect the arduino isn't shared with other devices (for example using a USB multipoint hub). If you're using a desktop with multiple USB ports (usually found at the back of the desktop case), unplug all other USB devices (keyboard, mouse etc) and reconnect them to a different USB. Use the fastest USB port available available on your computer (USB 3.0 if present) and have it dedicated for communication with the arduino. The reason the communication port goes unresponsive sometimes is because of the momentary fluctuations in the voltage and/or current if you have several devices connected to it.
Make sure you have a stable power supply for you computer, voltage drifts due to heavy loading can sometimes cause PC peripherals to disconnect/reconnect.
If this doesn't work, try this quick software fix. Just before the delay(30000) statement in your code, add the following:
if(!Serial) { //check if Serial is available... if not,
Serial.end(); // close serial port
delay(100); //wait 100 millis
Serial.begin(9600); // reenable serial again
}
This might at least ensure continued operation operation of your application with out requiring your intervention.
So in my case the problem was solved by connecting my computer through proper surge supressor, formerly i had connectected it to wall with a simple cable, and I have old 2 wire, non-grounded, electric installation in my flat.

Cannot connect Wifly to Arduino

I am just an Arduino beginner. I bought an Arduino Uno and a Wifly shield yesterday and I am not able to run the Wifly_Test example program come with WiFlySerial library.
When I look at Serial Monitor, I only saw 2 lines are printed out
1.Starting WiFly Tester.
2.Free memory:XXXX
How can I know that the Wifly Sheild that I bought is not faulty?
I soldered the heard ping to Wifly Shield and stacked it to Aurduino Uno and I can see the LEDs blinking on the Wifly Shield.
Do I need to reset the Wifly Sheild? How do I reset it?
Please point me to the most simple example on how to connect to the router.
I have also bought the shield and had trouble to start with.
If you have soldered the pins to the shield that should be fine but make sure you check they all have a connection and that they don't have solder running down the legs of the pins as this causes the shield to be temperamental.
Run the code below which is from the WiFly library (alpha 2 version) that can be found here:
http://forum.sparkfun.com/viewtopic.php?f=32&t=25216&start=30
Once you see that the shield has connected it will ask for an input, type $$$ and press enter... you have now entered the command line and CMD will be displayed.
If you do not know your network settings type scan and this will display them.
Then set your authentication by typing set wlan auth 3 (Mixed WPA1 & WPA2-PSK) or set wlan auth 4 (WPA2-PSK) this depends on the type of authentication you ise so pick the write one for your network.
Then type set wlan phrase YourPharsePhrase (Change YourPharsePhrase to whatever your WPA key is)
Then type join YourSSIDName (Change YourSSIDName to whatever your network name is)
You see something like this:
join YourSSIDName
Auto-Assoc YourSSIDName chan=1 mode=MIXED SCAN OK
Joining YourSSIDName now..
<2.15> Associated!
DHCP: Start
DHCP in 1234ms, lease=86400s
IF=UP
DHCP=ON
IP=10.0.0.116:2000
NM=255.255.255.0
GW=10.0.0.1
Listen on 2000
you are now connected to your network.
Hopefully this will get you up and running.
N.B. REMEMBER TO CAREFULLY CHECK YOUR PINS! I had great trouble with mine because only a small amount of solder is needed but enough to get a good connection, the balance of this was minute but enough that it wouldn't work. I used a magnifying to check mine in the end.
#include "WiFly.h" // We use this for the preinstantiated SpiSerial object.
void setup() {
Serial.begin(9600);
Serial.println("SPI UART on WiFly Shield terminal tool");
Serial.println("--------------------------------------");
Serial.println();
Serial.println("This is a tool to help you troubleshoot problems with the WiFly shield.");
Serial.println("For consistent results unplug & replug power to your Arduino and WiFly shield.");
Serial.println("(Ensure the serial monitor is not open when you remove power.)");
Serial.println();
Serial.println("Attempting to connect to SPI UART...");
SpiSerial.begin();
Serial.println("Connected to SPI UART.");
Serial.println();
Serial.println(" * Use $$$ (with no line ending) to enter WiFly command mode. (\"CMD\")");
Serial.println(" * Then send each command followed by a carriage return.");
Serial.println();
Serial.println("Waiting for input.");
Serial.println();
}
void loop() {
// Terminal routine
// Always display a response uninterrupted by typing
// but note that this makes the terminal unresponsive
// while a response is being received.
while(SpiSerial.available() > 0) {
Serial.write(SpiSerial.read());
}
if(Serial.available()) { // Outgoing data
//SpiSerial.print(Serial.read(), BYTE);
SpiSerial.write(Serial.read());
}
}
Sorry I forgot to mention , you reset the shield by going to the WiFly library and going to: WiFly/tools/HardwareFactoryReset
Then open the serial monitor and type in any character and this will start the reset.
Thanks everyone who tried to answer me. I finally solved my problem by using Arduino 0023 instead of 1.0.