The simplest bridge example won't work - Arduino Yun - c

I tried to modify the Temperature Web Panel example (found in arduino-1.5.6-rw/libraries/Bridge/examples/TemperatureWebPanel) for a light sensor. Unfortunately it seems even the simplest receive and transmit result over wifi doesn't work! I even commented out the working part to just send back some text to the browser as you can see, but I still see nothing in the browser:
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
// Listen on default port 5555, the webserver on the Yun
// will forward there all the HTTP requests for us.
YunServer server;
String startString;
long hits = 0;
void setup() {
Serial.begin(9600);
// For debugging, wait until the serial console is connected.
/*delay(4000);
while(!Serial);
Bridge.begin();
*/
// Bridge startup
pinMode(13, OUTPUT);
Bridge.begin();
digitalWrite(13, HIGH);
pinMode(A0, INPUT);
// Listen for incoming connection only from localhost
// (no one from the external network could connect)
server.listenOnLocalhost();
server.begin();
// get the time that this sketch started:
Process startTime;
startTime.runShellCommand("date");
while (startTime.available()) {
char c = startTime.read();
startString += c;
}
Serial.println("yeah\n");
Serial.println(startTime);
}
void loop() {
// Get clients coming from server
Serial.println("a\n");
YunClient client = server.accept();
// There is a new client?
if (client) {
Serial.println("Client!\n");
// read the command
String command = client.readString();
client.print('(This should definitely be sent over bridge)');
/*command.trim(); //kill whitespace
Serial.println(command);
// is "temperature" command?
if (command == "temperature") {
// get the time from the server:
Process time;
time.runShellCommand("date");
String timeString = "";
while (time.available()) {
char c = time.read();
timeString += c;
}
Serial.println(timeString);
int sensorValue = analogRead(A0);
// convert the reading to millivolts:
client.print("Current time on the Yún: ");
client.println(timeString);
client.print("<br>Current value: ");
client.print(sensorValue);
client.print("<br>This sketch has been running since ");
client.print(startString);
client.print("<br>Hits so far: ");
client.print(hits);
}*/
// Close connection and free resources.
client.stop();
hits++;
}
delay(50); // Poll every 50ms
}
I see the "a" multiple times in the serial monitor, but never see anything in the arduino.local/arduino/temperature url, just a blank response.
Furthurmore, after awhile it seems the Yun was disconnecting from the network, not accessible over http or ssh. How does one debug an issue like this, considering ssh is the main way to communicate with this computer?

After debugging step by step on my own configuration, I found that the code never advanced past Bridge.begin().
Upon further investigation, I found that the default Bridge baud rate of 250000 no longer matched the kernel baud rate of 115200.
Changing to: Bridge.begin(115200) ... fixed the issue for me.
To determine your kernel speed, run cat /proc/cmdline from a terminal into your Yun
See this link for more info: https://groups.google.com/forum/#!msg/linino/-rSmpjX4UOM/Cnjv-uzrlfgJ
If this isn't your issue, consider adding debug information (ie.. Serial.print()) in the actual source files for Bridge.cpp, etc. Unfortunately, it appears that Arduino/Linino devs often make breaking changes and do not have the resources to update documentation, examples, etc.

If you are on Windows, don't use 'arduino.local', because Windows has problems to resolve this host.
Have you tried with the IP address ?
You must televerse your script through wifi, and not through serial (in arduino Ide you must change the port)
Have you created the path 'arduino/www/'
You need a micro SD card plugged in to your Yún with a folder named “arduino” at the root. Inside the “arduino” folder, there must be a directory called “www”. You need to upload the sketch via WiFi to transfer the contents of the local “www” folder. You cannot transfer files via USB. Once uploaded, you can open your favorite browser and go to http://arduino.local/sd/TemperatureWebPanel.
you must open http://YUNS_IP/sd/TemperatureWebPanel

if you are using the Yun Shield u need to comment out the Serial commands or remove all references to serial as the Bridge and the Serial port all share the same hardware serial. I faced the same problem there was no connection.

Replace serial.begin(115...) by Bridge.begin().

Related

STM32 USB VCP (Virtual Com Port)

I generated a code for "stm32f103c8t6" with CubeMX for USB VCP, when I add "CDC_Transmit_FS" command to send data, the port isn't recognized by windows10!
what should I do? Here is the code which is compiled without error:
#include "stm32f1xx_hal.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
int main(void)
{
uint8_t Text[] = "Hello\r\n";
while (1)
{
CDC_Transmit_FS(Text,6); /*when commented the port is recognized*/
HAL_Delay(1000);
}
}
There are three things you need to check in my experience:
startup_stm32f405xx.s --> Increase the Heap size. I use heap size 800 and stack size 800 as well.
usbd_cdc_if.c --> APP_RX_DATA_SIZE 64 and APP_TX_DATA_SIZE 64
usbd_cdc_if.c --> add below code to the CDC_Control_FS() function
Code:
case CDC_SET_LINE_CODING:
tempbuf[0]=pbuf[0];
tempbuf[1]=pbuf[1];
tempbuf[2]=pbuf[2];
tempbuf[3]=pbuf[3];
tempbuf[4]=pbuf[4];
tempbuf[5]=pbuf[5];
tempbuf[6]=pbuf[6];
break;
case CDC_GET_LINE_CODING:
pbuf[0]=tempbuf[0];
pbuf[1]=tempbuf[1];
pbuf[2]=tempbuf[2];
pbuf[3]=tempbuf[3];
pbuf[4]=tempbuf[4];
pbuf[5]=tempbuf[5];
pbuf[6]=tempbuf[6];
break;
and define the uint8_t tempbuf[7]; in the user private_variables section.
Without the increased heap size, Windows does not react at all.
Without the point 3, Windows will send the baud rate information and then read the baud rate, expecting to get back the same values. Since you do not return any values, the virtual com port remains as driver-not-loaded.
If you do all of that, the Windows 10 out-of-the-box VCP driver can be used. No need to install the very old ST VCP driver on your system.
PS: I read somewhere turning on VSense makes problems, too. Don't know, I have not configured it and all works like a charm.
Put delay before CDC_Transmit_FS call - it will wait for the initiatialization. Your code should be like this
int main(void)
{
uint8_t Text[] = "Hello\r\n";
HAL_Delay(1000);
while (1)
{
CDC_Transmit_FS(Text,6); /*when commented the port is recognized*/
HAL_Delay(1000);
}
}
I had similar issue. I couldn't connect to a port and the port appears as just "virtual com port". I added while loop to wait for USBD_OK from CDC_Transmit_FS. Then it stars work even with out it or a delay after init function. I am not sure what the issue was.
while(CDC_Transmit_FS((uint8_t*)txBuf, strlen(txBuf))!=USBD_OK)
{
}
you may have to install driver to get device recognized as com port
you can get it from st site
if not installed the device is listed with question or exclamation mark on device manager
note that you cannot send until device get connected to host!
not sure that CubeMX CDC_Transmit_FS is checking for this
also instead of delay to resend you shall check the CDC class data "TXSstate"
is 0 mean tx is over.
I know it's a bit late, but I stumbled upon this post and it was extremely helpful.
Here is what I needed to do:
do the Line-Coding (I think only necessary on Windows-Systems)
increase Heap (Stack was left at default 0x200)
Here is what wasn't necessary for me (on a STM32F405RGT6 Chip):
change APP_RX_DATA_SIZE / APP_TX_DATA_SIZE (left it at 2048)
add a delay befor running CDC_Tranmit_FS()
Also some things to consider that happened to me in the past:
be sure to use a USB-Cable with data lines (most charging-cables don't have them)
double check the traces/connections if you use a custom board

How to print response to AT commands in Arduino serial port?

I want to print the response to AT command. I'm sending AT command but I'm not getting any response in the Arduino serial port. It's giving -1 instead of OK.
#include "SoftwareSerial.h"
String ssid = "connectify-krish";
String password = "12345678";
String myword= "";
SoftwareSerial esp(10, 11);
void setup() {
Serial.begin(9600);
esp.begin(9600);
esp.write("AT");
Serial.println(esp.read());
}
void loop() {}
As already pointed out in the comments you are not terminating the AT command line, so the modem will never respond to this.
Make sure you read V.250 and learn the difference between an AT command and an AT command line. ATI is an AT command, and "ATI I I\r" is a command line invoking this command three times in a row. Notice by the way in this example that you will get just one single Final result code for all three of them, i.e. the Final result code is a response to a complete command line and not to individual command invocations.
Then after fixing the sending of the command you must implement proper handling of the response. This includes reading and parsing what the modem sends back as a response to the sent command line. See this answer for the code structure and implementation hints.
As you've been told, terminate your AT commands with a carriage return character \r. Also you current code will read only a byte of the response, and thats if the response has even arrived since you included no delay at all. To communicate with the ESP interactively with the Serial monitor, I'd recommend using this:
#include <SoftwareSerial.h>
SoftwareSerial esp(10, 11);
void setup(){
Serial.begin(9600);
esp.begin(9600);
}
void loop()
{
while (Serial.available()) // forward data from monitor to esp
esp.write(Serial.read());
while (esp.available()) // forward data from esp to monitor
Serial.write(esp.read());
}
This basically makes your Arduino a conduit for communication between your PC and the ESP. You can send commands to the ESP with the Serial monitor and get their results immediately. Its great for testing commands. Just remember to set the serial monitor to BOTH NL & CR; this will serve you well for commands as well as any HTTP requests you send, as it appends \r\n to everything you send.
If you do want to write a sketch to talk to the ESP, you must provide some delay after sending a command to wait for the module to process the command and respond. The delay varies depending on the command, at least 500ms. The usual procedure is to define a timeout period for each command, depending on how long its expected to take, after which you 'give up' if there's no response yet. There are lots of libraries on GitHub that involve talking to some device using AT commands; study them to learn their techniques.

Using DHCP libraries results infinite loop

I have a code that uses DHCP libararies(package : 4.2.6) to get the hardware address of the DHCP client connected to the system. During this process after DHCP objects got initialized, i tried dhcp_connect() as follows which results into an infinte loop.
dhcpctl_initialize ();
status=dhcpctl_connect (&connection, "127.0.0.1", 7911, 0);
When i tried to debug the issue, i found a function "omapi_wait_for_completion"(in ompai/dispatch.c), has a do-while check for waiter object and its status, the object should change its state to ready to come out of the this loop, but this is never happened which results into an infinite loop.
Here i am just copying the loop as a reference.
do {
status = omapi_one_dispatch ((omapi_object_t *)waiter, t);
if (status != ISC_R_SUCCESS)
return status;
} while (!waiter || !waiter -> ready);
NOTE:
There is no issue when i run the binary generated from the code in system command line, but when i trigger the same command through an application we have this issue.
The application that triggers my binary doesn't uses DHCP libraries or files.
Please note that same binary with the same application is working
fine with older DHCP package (3.0.5).
Thanks in advance for your help.

Serial port not sending data

Yesterday, I started with some serial port communication. Today, I tried to open exactly the same sketch I used yesterday. It worked, but a few minutes later when I uploaded it again, it doesn't work at all.
Here's the code:
#include "Blink_main.h"
int pin = 1;
void pulsePin(int abc, int length){
digitalWrite(abc, true);
delay(length);
digitalWrite(abc, false);
}
void setup() {
pinMode(pin, OUTPUT);
Serial.begin(9600);
Serial.println("Hi serial!");
pulsePin(pin, 1000);
}
void loop() {
if(Serial.available() > 0){
Serial.println(Serial.read());
pulsePin(pin, 1000);
}
}
When opening the application, I don't see the "Hi serial!" message, When sending something, I don't get a message back and I don't see the LED flashing. Why is this happening?
You are using pin 1 to blink the led, move the led to another pin since it is used as the serial TX
Digital Pins 0-1/Serial In/Out - TX/RX - These pins cannot be used for digital i/o (digitalRead and digitalWrite) if you are also using serial communication (e.g. Serial.begin).
It look like the problem come from the Arduino board.
Firstly, try to upload a Serial example sketch.
If it doesn't work, try to reinstall the driver or change the COM port used.
If the problem is still happening, it's probably the ATMEGA8U2 or ATMEGA16U2 which is dead. You can test with an external USB to UART convert directly on pins 0 and 1

libssh2 session cleanup without blocking?

My app uses libssh2 to communicate over SSH, and generally works fine. One problem I have is when the remote host dies unexpectedly -- the remote host in this case is an embedded device that can lose power at any time, so this isn't uncommon.
When that happens, my app detects that the remote computer has stopped responding to pings, and tears down the local end of the SSH connection like this:
void SSHSession :: CleanupSession()
{
if (_uploadFileChannel)
{
libssh2_channel_free(_uploadFileChannel);
_uploadFileChannel = NULL;
}
if (_sendCommandsChannel)
{
libssh2_channel_free(_sendCommandsChannel);
_sendCommandsChannel = NULL;
}
if (_session)
{
libssh2_session_disconnect(_session, "bye bye");
libssh2_session_free(_session);
_session = NULL;
}
}
Pretty straightforward, but the problem is that the libssh2_channel_free() calls can block for a long time waiting for the remote end to respond to the "I'm going away now" message, which it will never do because it's powered off... but in the meantime, my app is frozen (blocked in the cleanup-routine), which isn't good.
Is there any way (short of hacking libssh2) to avoid this? I'd like to just tear down the local SSH data structures, and never block during this tear-down. (I suppose I could simply leak the SSH session memory, or delegate it to a different thread, but those seem like ugly hacks rather than proper solutions)
I'm not experienced with libssh2, but perhaps we can get different behavior out of libssh2 by using libssh2_session_disconnect_ex and a different disconnect reason: SSH_DISCONNECT_CONNECTION_LOST.
libssh2_session_disconnect is equivalent to using libssh2_session_disconnect_ex with the reason SSH_DISCONNECT_BY_APPLICATION. If libssh2 knows that the connection is lost, maybe it won't try to talk to the other side.
http://libssh2.sourceforge.net/doc/#libssh2sessiondisconnectex
http://libssh2.sourceforge.net/doc/#sshdisconnectcodes
Set to non-blocking mode and take the control of reading data from the socket to your hand by setting callback function to read data from the soket using libssh2_session_callback_set with LIBSSH2_CALLBACK_RECV for cbtype
void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
If you can't read data from the socket due to error ENOTCONN that means remote end has closed the socket or connection failed, then return -ENOTCONN in your callback function

Resources