I am trying to write a simple webserver on an Arduino to test a few things, but I couldn't find my Arduino with Ethernet on it.
"No worries" I thought, "I'll just write a socket server in python that acts as a proxy for the serial connection".
import socket
import serial
host = ''
port = 8001
buffSize= 1024
serverSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serverSocket.bind((host, port))
serverSocket.listen(1)
ser = serial.Serial('COM3', 115200, timeout=None, dsrdtr =False,rtscts =False,xonxoff =False)
print "Listening..."
send = ""
while 1:
conn, remoteAddr = serverSocket.accept()
print "Connection...."
data = conn.recv(buffSize)
print "Recieved"
ser.write("%s\n"%data)
print "Sent"
print "Attempting to get reply"
while ser.inWaiting()>0:
conn.send( ser.read())
conn.close()
serverSocket.close()
However, whatever I try, it seems that the connection made by the browser resets randomly and I'd get multiple rows of data. And the script resets the Arduino each time it connects or disconnects from the serial port. I tried using RealTerm and I got a proper answer, but python and serialness is just a mess.
Can anyone help me?
Use the tcp_serial_redirect.py script in the PySerial documentation. Is all you need.
Related
I am looking to learn if you know of any python libraries or methodologies that would allow me to do the following.
I am looking to run two python scripts, sender & receiver. I would like each to run on separate machines in Python. I want the sender to pass a data string to receiver over the internet.
Any idea on how I can do this?
Much appreciated!
If you want to accomplish this task you need to take a look at the python socket.py module (https://docs.python.org/3/library/socket.html).
An example for a sender script from (https://www.geeksforgeeks.org/socket-programming-python/):
# first of all import the socket library
import socket
# next create a socket object
s = socket.socket()
print ("Socket successfully created")
# reserve a port on your computer in our
# case it is 12345 but it can be anything
port = 12345
# Next bind to the port
# we have not typed any ip in the ip field
# instead we have inputted an empty string
# this makes the server listen to requests
# coming from other computers on the network
s.bind(('', port))
print ("socket binded to %s" %(port))
# put the socket into listening mode
s.listen(5)
print ("socket is listening")
# a forever loop until we interrupt it or
# an error occurs
while True:
# Establish connection with client.
c, addr = s.accept()
print ('Got connection from', addr )
# send a thank you message to the client. encoding to send byte type.
c.send('Thank you for connecting'.encode())
# Close the connection with the client
c.close()
# Breaking once connection closed
break
An example for a reciever script that can be run on the same machine or another machine:
# Import socket module
import socket
# Create a socket object
s = socket.socket()
# Define the port on which you want to connect
port = 12345
# connect to the server on local computer
s.connect(('127.0.0.1', port))
# receive data from the server and decoding to get the string.
print (s.recv(1024).decode())
# close the connection
s.close()
Here in the two examples the two scripts were running on the same machine but you can change that.
This document can be helpful too (https://docs.python.org/3/howto/sockets.html)
I want to send some simple information, like an int or a string, between two Python programs. I thought of doing it by having the programs read and write from a single-line file. But that doesn't seem to work, since one file seems to block the file. Especially since I want to check for updates every 1/12 of a second or so.
If it did work, my idea use case would be for one program to send a message with
with open('input.py','w') as file:
file.write('hello')
and receive it with
with open('input.py','r') as file:
print(file.read())
I've been looking into how to do it with sockets, but every 'simple' tutorial seems to be targeted some much more complex use case. So how do I do what I need to do in a way that'll actually work?
The best route to go is to use the socket library. This creates a client-server connection, where you can send strings between programs from there.
server.py:
import socket
s = socket.socket()
print "Socket successfully created"
port = 12345 # Reserve a port on your computer...in our case it is 12345, but it can be anything
s.bind(('', port))
print "Socket binded to %s" %(port)
s.listen(5) # Put the socket into listening mode
print "Socket is listening"
while True:
c, addr = s.accept() # Establish connection with client
print 'Got connection from', addr
c.send('Thank you for connecting') # Send a message to the client
c.close()
client.py:
import socket
s = socket.socket()
port = 12345 # Define the port on which you want to connect
s.connect(('127.0.0.1', port)) # Connect to the server on local computer
print s.recv(1024) # Receive data from the server
s.close()
From the terminal/shell:
# start the server:
$ python server.py
Socket successfully created
Socket binded to 12345
Socket is listening
Got connection from ('127.0.0.1', 52617)
# start the client:
$ python client.py
Thank you for connecting
As you can see, the client was able to receive the string "Thank you for connecting" by the server, thanks to the send() and recv() methods from the socket library.
I am trying to do wireless communications between a PC (macbook) and a Raspberry Pi 2 using python's socket module (python 2.7). The server is the PC and the client is the Pi.
When I run the code (server first then client) both scripts get stuck on the socket.accept() and socket.connect() methods respectfully.
What is funny is that when I do the reverse (Pi being the server and PC being the client) the code works fine, with data been sent correctly.
The scripts below are meant to loop forever whilst incrementing a counter sent over (I increment the port's after each succesful transfer to avoid '[Errno 48] Address already in use' (probably terrible practice I know))
My client script:
import socket
import sys
def read(port):
s = socket.socket()
host = '10.19.92.44' #(IP address of PC (server))
s.connect((host,port))
try:
msg = s.recv(1024)
s.close()
except socket.error, msg:
sys.stderr.write('error %s'%msg[1])
s.close()
print 'close'
sys.exit(2)
return msg
if __name__ == '__main__':
port = 1025
while True:
print 'hey, checking TCP socket'
data = read(port)
print 'i just read %s' % data
print 'port num is: %d' % port
port = port + 1
My server script:
import socket
import time
def send(data, port):
s = socket.socket()
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print 'Got connection from',addr
c.send(data)
c.close()
if __name__ == '__main__':
port = 1025
num = 1
while True:
print 'hey, sending data'
words = 'helloWorld'
data = words + str(num)
print 'send data: %s' % data
send(data,port)
port = port + 1
num = num + 1
As I mentioned when I swap roles (and replace the server IP address in the client script to the Pis 172.17.33.125) the code works fine...
Any ideas/suggestions?
Thank you very much
I don't have an immediate answer, but I have a couple of ideas.
Your PC and Pi seem to be in different networks. The PC's address is 10.19.92.44, while Pi's is 172.17.33.125. There's a probability that 10.19.92.44 isn't the address you need. In order to find out what is the correct PC IP address to use in the application:
Issue networksetup -listallhardwareports to figure out the name of your wifi interface (should be like en0, en1).
Issue ifconfig, find the wifi interface. The IP address attached to this interface is the one you need.
Another option is to install wireshark on the PC, set up a working system (server-Pi, client-PC) and use wireshark to capture the traffic between the PC and Pi. Wireshark makes it easy to figure out IP addresses of both parties. I would advise to have this program installed whenever you want to debug a complicated networking issue.
I am currently developing a system where I need to send notification to Raspberry to run a Python file. It is much like a observer pattern design where my server is publisher and Raspberry is the observer. Worth to note that, I actually need to interact with one Raspberry at the time (even I have dozens of them). Specifically, on a specific event, I need to warn a single Raspberry that it has to take an action.
I searched for it literally for all the night but I could not find anything coming handy. Nothing really give me a clue how to implement this.
The most close answer I could find is this technology firm's product called PubNub which can actually work. However, as I need is a one-to-one interaction, this might be unnecessary because it is designed to publish a data to multiple clients.
Long story short, I need to trigger Raspberry to take some action in accordance to the some data coming from the server, whenever it receives the data.
Server is running on Amazon and implemented with Python 2.7.
Please do not hesitate to ask me for further detail, if I am missing any.
Thanks for all the supports,
EDIT
Just a recent update with an improvement to my answer. As far as I understand, sockets are able to manage this process. Such as from client (Raspberry in my case) listening for the server and server sending some data. Taken from this site, I managed to make a sample run on my computer, from my local. I used Port 5000 as their 'meeting point'.
Below is the code:
client.py
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 1024
MESSAGE = b"Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print("received data:", data)
server.py
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 20 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print('Connection address:', addr)
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
print("received data:", data)
conn.send(data) # echo
conn.close()
However, I still have some questions.
Firstly, I want to learn whether the same thing work when I deploy the project and how. If that will work - lets say I have an url for the server like 'www.thisisanexampleurl.com' - simply assignign a port for it, will work?
Secondly, assuming first question is done, what is the way of making it continous so that it does not stop after receiving and sending data once. Because currently, when it makes the data transfer, it stops working.
Thanks again for the all support and again please do not hesitate to ask me for the further details i am missing any.
You should be able to do something this simple:
Run something like this on your pi:
import socket
s = socket.socket()
host = ""
port = 12345
s.bind((host, port))
s.listen(5)
while True:
try:
clientsock, addr = s.accept()
except OSError:
continue
message = clientsock.recv(20)
#the code you want to run
print("doing %s" % message)
clientsock.close()
And this on your server every time you want the pi to take action:
import socket
s = socket.socket()
host = "0.0.0.0"
port = 12345
s.connect((host, port))
s.send("foo")
s.close()
Have a look at Pyro4. It lets you avoid having to write network code at all and just write code that calls remote Python objects as if they were running on the same machine. In your case, the server could call a normal Python method on your Raspberry Pi to do something. It has many features but you can start with something extremely simple.
raspberry pi code:
import Pyro4
#Pyro4.expose
class Raspberry:
def something(self, arg):
print("called with:", arg)
return "hi from pi"
Pyro4.Daemon.serveSimple({Raspberry: "raspberry"})
server code to make the pi do something:
import Pyro4
rasp = Pyro4.Proxy("PYRONAME:raspberry")
print(rasp.something(42))
I am using TCP sockets to communicate between my server and clients. The server code and socket code are as below:
server:
from socket import *
HOST = 'xx.xx.xx.xx'
PORT = 1999
serversocket = socket(AF_INET,SOCK_STREAM)
serversocket.bind((HOST,PORT))
print 'bind success'
serversocket.listen(5)
print 'listening'
while True:
(clientsocket, address) = serversocket.accept()
print ("Got client request from",address)
#clientsocket.send('True')
data = clientsocket.recv(1024)
print data
clientsocket.send('True')
clientsocket.close()
client:
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port on the server given by the caller
server_address = ('xx.xx.xx.xx', 1999)
print >>sys.stderr, 'connecting to %s port %s' % server_address
sock.connect(server_address)
try:
message = 'This is the message. It will be repeated.'
print >>sys.stderr, 'sending'
for x in range (0,1):
name=raw_input ('what is ur name')
print type(name)
sock.send(name)
print sock.recv(1024)
finally:
sock.close()
I am able to communicate with the server from client and able to send and receive data. But the problem I am facing is that I am not able to send and receive data continuously from the server. I have to restart my client code on my laptop to send and receive data again from the server. The way the above client code is working is that when I give a keyboard input, then the socket sends data to server and server responds back. But in the client code, in the for loop if I do two iterations, for the second iteration the data I enter from keyboard is not reaching server. I need to restart my client code to send data again. How do I fix this ?
Also, when once client is connected to the server, the other cannot connect to the server. Any ideas on how to do this ?
You need to design and implement a protocol that specifies what each side is supposed to do and then implement that protocol. You're expecting it to work by magic.
For example:
data = clientsocket.recv(1024)
I suspect you are expecting this to receive a "message". But TCP has no notion of messages. If you need to send and receive messages, you need to define precisely what a "message" is for your protocol and write code to send and receive them.
It may be helpful to look at the specifications for other protocols that use TCP such as HTTP, FTP, or IRC. It really is worth the time to write out a specification of your protocol before you write any code. It will save a lot of pain.