I'm trying to send packets of json data using python code to the arduino over ethernet udp protocol. It worked fine before, but then we had to switch devices--first from an older Mega that had bootloader problems to an uno, then to a newer Mega 2560 for more memory--and now the terminal is telling me the proper arduino port is busy when I run the listening program on it.
First I run this arduino code:
#include <ArduinoJson.h>
#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[] = {
0x90, 0xAD, 0xDA, 0x00, 0x42, 0x5B };
IPAddress ip(172,16,174,146);
unsigned int localPort = 8080; // local port to listen on
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
void loop() {
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);
}
}
Then this python sending code:
#!/usr/bin/env python
from __future__ import print_function
##################################################################################
# command line:
# python read_event_to_arduino.py --in_files /data/i3home/elims/display3D/event_files/data_dict.p
# --port /dev/ttyACM0
# --baud_rate 115200
# --sleep_time 5
##################################################################################
###################### PRINTOUTS ########################
import os, sys, optparse
import socket
print ('########################################################################################')
print ('#### This job is running on {0} ... '.format(socket.gethostname()) )
print ('########################################################################################')
print (' ')
#########################################################
from optparse import OptionParser
import serial, time, pickle
import numpy as np
#########################################################
#### defining pulse list...
#########################################################
class pulseList():
def __init__(self, dom, string, time, charge, width):
self.dom = dom
self.string = string
self.time = time
self.charge = charge
self.width = width
def __repr__(self):
return repr( (self.dom, self.string, self.time, self.charge, self.width) )
#########################################################
#### parsing options
#########################################################
usage = "%prog [options] <inputfiles>"
parser = OptionParser(usage=usage)
parser.add_option("-i", "--in_files", type = "string", default = [],
help = "Path/Name of the input pickle file")
parser.add_option("-n", "--num_events", type = "int", default = 0,
help = "Number of events to be displayed (default: all)")
parser.add_option("-d", "--port", type = "string", default = "/dev/ttyACM0",
help = "arduino device port")
parser.add_option("-b", "--baud_rate", type="int", default = 115200,
help = "baud rate of arduino board")
parser.add_option("-s", "--sleep_time", type="int", default = 50,
help = "break time between sending each events")
(options, args) = parser.parse_args()
#### note1: if software not recognizing port:
#### sudo usermod -a -G dialout <user name>
#### sudo chmod a+rw <port location>
#########################################################
#### setting up input file and arduino...
#########################################################
in_files = options.in_files
port = options.port
baud_rate = options.baud_rate
sleep_time = options.sleep_time
in_file = '/data/i3home/elims/display3D/event_files/data_dict.p'
data = pickle.load(open(in_file, 'rb'))
arduino = serial.Serial(port, baud_rate, timeout=.1)
time.sleep(1)
print ('in_file: {0}'.format(in_file))
print ('arduino: {0} with a baud rate of {1} Hz'.format(port, baud_rate))
print (' ')
#########################################################
#### reading in data from pickle file...
#### NOTE1: write '-1' to denotes end of each pulse
#########################################################
#event_map = []
for index, event in enumerate(data):
print ( '################## Event {0} with {1} hits ##################'.format(index, len(data[event])) )
pulse_map = []
for hit in data[event].items():
#current_hit = pulseList(hit[1]['dom'], hit[1]['string'], hit[1]['time'], hit[1]['charge'], hit[1]['width'])
current_hit = [hit[1]['time'], hit[1]['dom'], hit[1]['string'], hit[1]['charge'], hit[1]['width']] ## python list
pulse_map.append(current_hit)
pulse_map.sort(key=lambda h:h[0])
##### double check pulse map is timely sorted
for j, pulse in enumerate(pulse_map):
print ('pulse {0}: {1:.4f}, {2}, {3}, {4:.4f}, {5}'.format(j, pulse[0], pulse[1], pulse[2], pulse[3], pulse[4]))
print (' ')
#########################################################
#### sending number of hits in the current event to arduino...
#########################################################
info = [len(pulse_map), pulse_map]
print ( '... sending {0} to arduino ... '.format(str(info[0]).encode()) )
arduino.write(str(info[0]).encode())
time.sleep(2)
for j, pulse in enumerate(pulse_map):
for information in pulse:
arduino.write(str(information).encode())
time.sleep(2)
arduino.write('-1')
time.sleep(5)
#arduino.write(str(pulse_map))
time.sleep(sleep_time) #give the connection a second to settle
I use the following linux command in terminal: python read_event_to_arduino.py --baud_rate 9600 --port /dev/ttyACM2
and get this error:
File "read_event_to_arduino.py", line 71, in
arduino = serial.Serial(port, baud_rate, timeout=.1)
File "/data/i3home/jbelenky/pySerial/pyserial-2.7/serial/serialutil.py", line 282, in init
self.open()
File "/data/i3home/jbelenky/pySerial/pyserial-2.7/serial/serialposix.py", line 289, in open
self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
OSError: [Errno 16] Device or resource busy: '/dev/ttyACM2'
Ultimately I'm going to need an ethernetudp code that parses json data and sends it to the arduino, but for now I just need to get the connection working again.