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.
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 am using stm32f0 MCU.
I would like to transmit every single byte received from the uart out of the uart. I am enabling an interrupt on every byte received from uart.
My code is quite simple.
uint8_t Rx_data[5];
//Interrupt callback routine
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1) //current UART
{
HAL_UART_Transmit(&huart1, &Rx_data[0], 1, 100);
HAL_UART_Receive_IT(&huart1, Rx_data, 1); //activate UART receive interrupt every time on receiving 1 byte
}
}
My PC transmits ASCII 12345678 to stm32. If things work as expected, the PC should be receiving 12345678 back. However, the PC receives 1357 instead. What is wrong with the code?
Reenabling interrupts may be inefficient. With a couple of modifications it is possible to keep the interrupt active without needing to write the handler all over again. See the example below altered from the stm32cubemx generator.
/**
* #brief This function handles USART3 to USART6 global interrupts.
*/
void USART3_6_IRQHandler(void)
{
InterruptGPS(&huart5);
}
void InterruptGPS(UART_HandleTypeDef *huart) {
uint8_t rbyte;
if (huart->Instance != USART5) {
return;
}
/* UART in mode Receiver ---------------------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) == RESET) || (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) == RESET)) {
return;
}
rbyte = (uint8_t)(huart->Instance->RDR & (uint8_t)0xff);
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
// do your stuff
}
static void init_gps() {
__HAL_UART_ENABLE_IT(&huart5, UART_IT_RXNE);
}
You should make a tx array buffer as well, and use interrupt for writing as well (The first write if not enabled yet, should be sent immediately).
There should be examples of this for STM32 around.
You should probably switch the two lines: Transmit and Receive. The Transmit function waits for a timeout to send the character, in meantime the next received character is missed.
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.
I try to implement a i2c slave receiver interrupt service routine on a stm32f4.
Here is my smart piece of code.
void I2C2_EV_IRQHandler()
{
switch (I2C_GetLastEvent(I2C2))
{
//The address sent by the master matches the own address of the peripheral
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
//The slave stretches SCL low until ADDR is
//cleared and DR filled with the data to be sent
I2C_ClearFlag(I2C2,I2C_FLAG_ADDR);
break;
//The application is expecting a data byte to be received
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
I2C_ReceiveData(I2C2);
break;
//The application is expecting the end of the communication
//Make sure that both ADDR and STOPF flags are cleared
//if both are found set.
case I2C_EVENT_SLAVE_STOP_DETECTED:
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_ADDR) == SET)
I2C_ClearFlag(I2C2,I2C_FLAG_ADDR);
if(I2C_GetFlagStatus(I2C2,I2C_FLAG_STOPF) == SET)
I2C_ClearFlag(I2C2,I2C_FLAG_STOPF);
}
}
The interrupt becomes called and I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED case is entered.
The SCL is low now. The reference manual says if I clear the address flag, the clock will continue and data will be sent (Page 579 - Slave receiver). In my opinion the interrupt always becomes called if any data arrives and next state will be I2C_EVENT_SLAVE_BYTE_RECEIVED.
I can not find any example from stm or via google. Can anybody help me or show me an example.
now it works. My problem was that I was not able to reset the ADDR and the STOPF register with the given commands out of reference manual. But if do it in a loop it works fine for me. Here my working Interrupt Routine.
void I2C3_EV_IRQHandler()
{
switch (I2C_GetLastEvent(I2C3))
{
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
STM_EVAL_LEDOn(LED3);
STM_EVAL_LEDOff(LED5);
break;
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
STM_EVAL_LEDToggle(LED4);
STM_EVAL_LEDOff(LED3);
I2C_InputBuffer[I2C_InputBufferIndex++] = I2C_ReceiveData(I2C3);
break;
case I2C_EVENT_SLAVE_STOP_DETECTED:
STM_EVAL_LEDOn(LED6);
STM_EVAL_LEDOff(LED4);
break;
}
I2C_CleanADDRandSTOPF();
if(I2C_InputBufferIndex > MOTOR_PACKAGE_SIZE-1)
{
motorHandleEvent(I2C_InputBuffer);
I2C_InputBufferIndex = 0;
uint8_t resetIndex;
for(resetIndex = 0; resetIndex < MOTOR_PACKAGE_SIZE; resetIndex ++)
I2C_InputBuffer[resetIndex] = 0;
}
}
inline void I2C_CleanADDRandSTOPF()
{
while ((I2C3->SR1 & I2C_SR1_ADDR) == I2C_SR1_ADDR)
{
volatile uint32_t temp;
temp=I2C3->SR1;
temp=I2C3->SR2;
}
while ((I2C3->SR1&I2C_SR1_STOPF) == I2C_SR1_STOPF)
{
volatile uint32_t temp;
temp=I2C3->SR1;
I2C3->CR1 |= 0x1;
}
}
The hardware is doing clock stretching to ensure that the slave is keeping up with the master. The slave first waits to get an address match. Then you get interrupt while SCL is held low. This allows slave to basically provide flow control to the master. The master detects that SCL is being held low by slave and it will wait for it to be released before master sends any more data. So you won't get additional interrupts on data being received because the master won't send any more data until you let SCL go high. You can read about clock stretching here http://en.wikipedia.org/wiki/I%C2%B2C
How to find out the sender's ip address of a udp packet that was received on a device running iOS 3.2 or higher?
For example, if using Python on a computer, I'd use SocketServer.UDPServer which takes a subclass of SocketServer.BaseRequestHandler which defines the handle callback. When a packet arrives, the callback is called and the sender's ip address would be in self.client_address, where self is the SocketServer.BaseRequestHandler instance.
Unfortunately, I don't know how to extract this information or gain access to the associated ip header when programming in Objective C and using the frameworks provided for iOS.
Right now the only solution I have is to explicitly write the sender's ip on the body of the udp packet, but I'd rather not rely on the sender putting that information there if I don't have to.
You didn't mention what API you are using to receive the packet. Don't write the IP address into the packet itself because the packet may go through a number of network address translations before it gets to you.
You can use regular BSD sockets to acheive this task. There are also a few Foundation classes that wrap around BSD sockets, but I haven't used them personally, so I can't give you a decent example.
// for IPv4 (IPv6 is a little different)
ssize_t received;
char buffer[0x10000];
struct sockaddr_in listenAddr;
struct sockaddr_in fromAddr;
socklen_t fromAddrLen = sizeof fromAddr;
listenAddr.sin_family = AF_INET;
listenAddr.sin_port = htons(12345); // change to whatever port
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);
int s = socket(AF_INET, SOCK_DGRAM, 0); // create UDP socket
if (s == -1)
exit(1); // failed to create socket
if (bind(s, (struct sockaddr *) &listenAddr, sizeof listenAddr))
exit(2); // failed to bind to port 12345 for any address
received = recvfrom(s, buffer, sizeof buffer, 0, (struct sockaddr *)&fromAddr, &fromAddrLen);
if (received == -1)
exit(3); // some failure trying to receive data
// check the contents of buffer, the address of the source will be in
// fromAddr.sin_addr.s_addr but only if (fromAddrLen == sizeof fromAddr)
// after the call to recvfrom.
char display[16] = {0};
inet_ntop(AF_INET, &fromAddr.sin_addr.s_addr, display, sizeof display);
NSLog (#"The source is %s.", display);
// could show "The source is 201.19.91.102."