i am new to this forum and the whole thing with Processing.
I have a specific question to ask and thanks a lot for your time and thoughts!
How can i connect my Arduino with Ethernet Shield, getting temperature values from a sensor so they can be seen to a processing script?
In a straight Arduino script, one gets the value, connects from the ethernet shield to a server and does what one likes. I have accomplished that.
In my case i want Arduino to just run the script of reading an analog input value from the sensor.
Is it possible?
I have made the serial connection work and read the values alright through the usb, but with ethernet shield? How can i get the value that arduino reads WITHOUT USB/Serial connection?
ps. i am using WAMP server etc, Windows 7
I am trying the UDP connection script example for both arduino and processing from http://arduino.cc/en/Tutorial/UDPSendReceiveString, but
1)i ain't sure if that's what i need,
2)i have excluded from firewall ports 6000, 8888 for my tests and have put the IP address of my Arduino at the Arduino script and "localhost" at the Processing script
THE CODE COPIED FOR BETTER USE HERE
/*
UDPSendReceive.pde:
This sketch receives UDP message strings, prints them to the serial port
and sends an "acknowledge" string back to the sender
A Processing sketch is included at the end of file that can be used to send
and received messages for testing with a computer.
created 21 Aug 2010
by Michael Margolis
This code is in the public domain.
*/
#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 mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
delay(10);
}
/*
Processing sketch to run with this example
=====================================================
// Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message
*/
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void draw()
{
}
void keyPressed() {
String ip = "192.168.1.177"; // the remote IP address
int port = 8888; // the destination port
udp.send("Hello World", ip, port ); // the message to send
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String ip, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
Read those values into a file and use that file to send data to processing. http://py.processing.org/reference/createReader.html
Great scheme. Only one problem. It works perfectly on my system. I loaded my Arudino Uno R3 with your Arduino sketch and loaded the Processing sketch as well. Worked like a charm, first try. Didn't change anything on my Arduino, Windows system, Processing (2.0.3), network, etc.
Could be you have a Arduino board problem (unlikely) or an Ethernet shield problem (sadly, more likely). You could have a network problem (even more likely).
Try Wireshark. You will really just be guessing until you take a look at the Wireshark output. Note that Wireshark has filters. You will need them. Filter out all of the non-UDP traffic.
Related
I have tried many different drivers and cannot successfully send data from the uC to the computer over USBSerial. I am trying the mbed-official USBSerial driver but have had the same results with the KL25Z fork and the ST micro fork as well as mbed OS2 an OS5. I am able to receive bytes freely from the computer to the uC but I cannot send data the other direction.
I have tried 3 different methods to send data to the computer: _putc(), writeBlock(), and printf(). For all three methods, the first byte is sent back to the computer successfully but then the device gets stuck in an endless while loop on line 863 in USBDevice.cpp. This is the 'Wait for completion' portion of the USBDevice::write() function.
I do not feel that I have enough knowledge about USB interfaces to properly debug this driver.
I have published my test program here.
#include "mbed.h"
#include "USBSerial.h"
//Virtual serial port over USB
USBSerial serial;
DigitalOut thisLED(LED1);
char temp[1];
void receiveSerial()
{
while (serial.readable())
{
temp[0] = serial._getc();
serial._putc(temp[0]);
//serial.writeBlock((uint8_t *) temp,1);
//serial.printf(temp);
}
}
int main(void) {
serial.attach(&receiveSerial);
while(1)
{
thisLED = !thisLED;
wait(1);
}
}
I'm trying to trigger an interrupt function each time I receive a broadcast message on a given port of an STM32 board (Nucleo f429zi). The communication protocol I use is UDP and the mbed library is UDPSocket which inherits from Socket.
Does anyone have an idea how to achieve it?
Edit:
Thanks to PeterJ's comment I found an interesting (but deprecated) member function of the class Socket which is called attach(). This method registers a callback on state change of the socket (recv/send/accept).
Since I have an incoming broadcast on the socket, there is no state change in my case (only receiving data, never sending). Is there a way I could use this attach() method to detect every message received?
// Open Ethernet connection
EthernetInterface eth;
eth.connect();
// Create an UDP socket for listening to the broadcast
UDPSocket broadcastSocket;
broadcastSocket.open(ð);
broadcastSocket.bind(BROADCAST_PORT);
// Function to call when a broadcast message is received
broadcastSocket.attach(&onUDPSocketEvent);
void onUDPSocketEvent(){
printf("UDP event detected\n");
}
attach has been replaced by sigio, but I don't think it's going to do what you want. A nice way would be to spin up a new thread, and use this thread to handle the socket.
void onUDPSocketEvent(void* buffer, size_t size) {
printf("UDP event detected\n");
}
void udp_main() {
// Open Ethernet connection
EthernetInterface eth;
eth.connect();
// Create an UDP socket for listening to the broadcast
UDPSocket broadcastSocket;
broadcastSocket.open(ð);
broadcastSocket.bind(BROADCAST_PORT);
void* recvBuffer = malloc(1024);
while (1) {
// this blocks until next packet comes in
nsapi_size_or_error_t size = broadcastSocket.recvfrom(NULL, recvBuffer, 1024);
if (size < 0) {
printf("recvfrom failed with error code %d\n", size);
}
onUDPSocketEvent(recvBuffer, size);
}
}
int main() {
Thread t; // can pass in the stack size here if you run out of memory
t.start(&udp_main);
while (1) {
wait(osWaitForever);
}
}
(note that the callback function does not run in an ISR - so not in an interrupt context - but I assume you don't actually want that).
Edit: I have created mbed-udp-ping-pong which shows how to listen for UDP messages on a separate thread.
I have a processing program working on a local machine. It reads data from a local udp port and uses this data to draw circles on my screen. It works, so that great.
But in production the program has to run on an other computer. And I cant get it to work. Processing is presenting me this error message:
opening socket failed!
> address:192.168.1.118, port:6666 [group:null]
> Cannot assign requested address: Cannot bind
Of cource I checked the IP adress and these are OK as it works fine on the local machine. Here is my code for the UDP part:
// import UDP library
import hypermedia.net.*;
String HOST_IP = "192.168.1.118";
UDP udp; // define the UDP object
// get an array ready
int num = 20;
int[] xx = new int[num];
int[] yy = new int[num];
void setup() {
size(1024, 768);
smooth();
//noStroke();
// create a new datagram connection on port 6666
udp = new UDP(this, 6666, HOST_IP);
udp.listen( true );
}
//process events
void draw() {;}
/**
* To perform any action on datagram reception, you need to implement this
* handler in your code. This method will be automatically called by the UDP
* object each time he receive a nonnull message.
* By default, this method have just one argument (the received message as
* byte[] array), but in addition, two arguments (representing in order the
* sender IP address and his port) can be set like below.
*/
// void receive( byte[] data ) { // <-- default handler
void receive( byte[] data ) {
background(255);
// get the "real" message =
// forget the ";\n" at the end <-- !!! only for a communication with Pd !!!
data = subset(data, 0, data.length-2);
String message = new String( data );
// print the result
println(message );
On both machines I use Windows XP And they are connected via a switch and udp cables.
I don't know where to start troubleshooting and how. Any ideas?
At the moment I have an Arduino board with an Ethernet Shield connected to a router. My computer connects to this router via Wi-Fi. My board and my computer send UDP messages back and forth to each other. My computer is a client, and the board is a server. However I noticed, that when I send a longer UDP message from my computer, and then a shorter UDP message, the Arduino accepts the shorter message, then followed by remaining bits from the longer message.
For instance: if I send "Hello World" from my computer, followed with "Test"; the Arduino will not read the second message as "Test", but rather: "Testo World".
I thought perhaps in was a problem from the Arduino end first. The Arduino stores the messages temporarily in an array called packetBuffer. I tried clearing this buffer before I receive a new message each time. The buffer would clear, but then I would receive the faulty message again.
So I assume the culprit is the computer, the client. On the computer end I have a processing sketch that sends the UDP messages. The example below is not the sketch itself; however it is by far a simpler example that still provides the exact symptoms as I described with my original sketch.
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // Create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void keyPressed() {
String IPaddress = "192.168.1.177"; // The remote IP address
int port = 8888; // The destination port
if (keyCode == UP)
{
udp.send("Test", IPaddress, port );
}
else
if (keyCode == DOWN)
{
udp.send("Hello World", IPaddress, port );
}
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String IPaddress, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
How could I get the sketch to send the right messages?
Of course I am more than willing to provide more information.
There wasn't a direct solution to this problem; so I ended up resorting to a work around. The work around involves dynamically adding zeros to all strings sent to the Arduino so there is always 10 characters sent.
For instance:
If I am to send "Hello Bot", the actual string sent is "Hello Bot0". If I sent an additional message like "Test" after that, the string sent to the Arduino would be "Test000000". The additional zeros would cover up the overlapping characters. One problem with this work around is that I had to prepare the Arduino to accept the zeros also. This work around is also kind of messy for the code. It does work though.
Here's a snippet of code from the computer (client) side. The Arduino code obviously just had to be adjusted to account for the zeros.
public void Send() { //bang button named "Send" activates function
String txtSend = comField.getText(); //Grab text from a textbox to be sent
int txtSendLength = txtSend.length();
for(int i = 0; i < 10-txtSendLength; i++){ //Add zeros until it has 10 char
txtSend = txtSend + "0";
}
udp.send(txtSend, ip, port);
comField.clear(); //Clear the textbox
}
Behold, the very simple and crude solution!
I believe your issue is with properly clearing the buffer. I found a line of code that goes through and clears each character, since it is a character array. There is theoretically no buffer to clear once it is read.
Use:
for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;
Once you read the data, and that will clear the array. I also found out that when trying to do logic on the data that was received, in order to control some output, I needed to first convert the packetBuffer to a string. After that, all seemed to work correctly.
Hope that help.
The UDPSendReceive.pde example bundled with the IDE works fine out of the box and displays the correct output on the serial monitor when it receives UDP packets, but seems to disable all the pinOutputs?
#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 mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
pinMode(12, OUTPUT);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
digitalWrite(12, HIGH); // set the LED on
}
delay(10);
}
Even just changing the loop to be
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
digitalWrite(12, HIGH);
}
means nothing happens on my outputs (in this case an LED)
Update - Just noticed the SPI include in your code.The SPI library uses pin 12 (for MOSI) so its already reserved.
Previous:
Not sure which Ethernet shield/board you are using, but typically they use SPI protocol to communicate over pins 10-13. Pin 12 is used for MISO. (That's Master In, Slave Out - so its used by the Ethernet device (Slave) as output to the Aurduino's in (Master).
So pins 1 thru 9 should be fine to use as an LED indicator.
The information provided by JDH is correct. Ethernet/SPI uses several pins to communicate with the Ethernet shield. The rest are free for your use. See http://arduino.cc/en/Reference/SPI for some details. The Connections section shows what pins are used by several common Arduino boards. For the Uno and Duemilanove it's pins 10-13.