How to send data over CAN-Bus using ESP32 Module using MicroPython? - esp32

I have an ESP32 module connected to my computer. I am using Thonny IDE to program my ESP32 device using micropython code. I am trying to send data over CAN bus but I m getting error.
code:
from machine import CAN
can = CAN(mode=CAN.NORMAL, baudrate=500000, pins=('P22', 'P23'))
can.send(id=12, data=bytes([1, 2, 3, 4, 5, 6, 7, 8]))
can.recv()
error:
ImportError: can't import name CAN

At the time of writing this answer, according to this GitHub issue, the CAN API doesn't seem to be supported on the ESP32 build of MicroPython.
There is a pull request for an implementation, but is currently not working.

Related

How to read files from a SD card connected to ESP32 an then transfer/upload/send them with Micropython to Raspberry Pi?

I am working on a project, basically my proposal consist in a solution designed under server/client paradigm, on host side I have mounted an Ubuntu Server 20.4 LTS (64 Bits) on a raspberry pi and setup Flask (1.1.1) as a restful web service, on the other side I have the ESP32 with Micropython (v1.19.1) as a client that is sending data thru http to the web API.
So far so good, but I am planning on keeping log files as back up on the SD card connected to ESP32 for down time communication scenarios between server and client, since the down time period could be from a few hours to a whole day, I was thinking on keeping data in raw format in files generated by the hour in text plain, then eventually whenever the connection gets stablished the ESP32 can send files to server, so data can be parsed and do whatever was missing on the flow.
I also know that I could do the data parsing on client side and send a bunch of request to the Web API but giving the condition that the down time can last for several hours this could affect the performance of the main task on the ESP32 which is to collect data from sensors and prepare it to be sent to the raspberry pi.
What have I tried so far?, well I already have the code to read files from a SD card with ESP32 but due to the constraints on Micropython I am not able to send them thru http since the urequests library does not support it, despite that Flask on server side can handle it without problem.
import urequests
from machine import Pin, SPI
import machine, sdcard, os
spi = SPI(1, baudrate=10000000, polarity=0, phase=0,
miso=Pin(13),
mosi=Pin(12),
sck=Pin(14))
sd = sdcard.SDCard(spi, Pin(27))
os.mount(sd, '/sd')
files = [
('20220510_08', open('/sd/20220510/20220510_08.csv','csv')),
('20220510_09', open('/sd/20220510/20220510_09.csv','csv'))
]
payload = {}
headers = {'Content-Type': 'multipart/form-data'}
host = "http://192.168.0.25:5000/uploadLogFile"
response = urequests.request("POST",url = host, headers=headers,files = files)
TypeError: unexpected keyword argument 'files'
I was also thinking on setting up the FTP service on the raspberry pi, and look for a FTP client for the ESP32 in Micropython, so files can be transfer.
I think in theory makes sense but I wonder if anyone else has made something similar and have a code sample to share or either if someone has any better recommendation, since I am still new to Micropython programming I might be missing sight of something else worth of reviewing .
I thank you all in advance.
Regards

Is there anyway to send data through RPi and the Mac OS X wirelessly?

I am trying to build a robot that captures images from the RPi camera that is in installed, and try to sent it over to my Mac to do the image recognition and sent the result back. The robot was controlled by the Raspberry Pi 3 Model B. I have tried to communicate through socket but the whenever the it tries to connect, it always says “Connection refused” Any suggestions on new ways to communicate the RPi and the Mac wirelessly?
This is the code for the Server:
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8000))
server.listen(0)
connection = server.accept()[0].makefile('wb')
print("success")
This is the code for the Client:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
connection = client.makefile('rb')
print('connection sucessful')
Remember: I am just trying to make sure that the connection between the Raspberry Pi and the Mac is successful.
I just figure it out. I just noticed that before I even connect, I am already connected to the RPi using SSH. I was using this so I could edit the code of the RPi. So what I did is that I connected the RPi to a different device, and then run the server code on the Mac, and the client on the RPi. It was a success.
Sorry if you were having a hard time answering my question. After all, it was just a mistake noticing the SSH connection.

Unable to read information from USB with PyUSB in Windows 10. (Connects ok)

I am running Python 3 with Anaconda in a Windows 10 machine.
I am trying to connect to a usb barcode scanner in order to read barcodes and store them in variables in other python routine. I have found an example using PyUSB library and tried it. After a few modifications I was able to run it without raising errors. The program connects to the usb with the following code:
import usb.core
import usb.util
def main():
# Find usb device
dev = usb.core.find(idVendor=0x05E0, idProduct=0x1200)
# Raise error if device not found
if dev is None:
raise ValueError('Device not found')
else:
# Set configuration of device
dev.set_configuration()
endpoint = dev[0][(0,0)][0]
data = None
while True:
try:
dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, timeout=1)
print(data)
except usb.core.USBError as e:
data = None
if e.args == ('Operation timed out',):
print("ERROR")
continue
if __name__ == '__main__':
main()
As I say the program runs correctly and finds the usb. Nonetheless, data (barcode number) is never printed because the program seems to get stuck at following line:
dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, timeout=1)
Can you help me?
Thank you very much in advance!
Using PyUSB to read barcodes is too complicated.
It is recommended to set the COM port mode in the following way and communicate with PySerial.
Download the device driver from this page.
USB CDC DRIVER FOR WINDOWS
Set the scanner to COM port mode with the procedure and setting barcode described on this page.
EMULATING A COM/SERIAL PORT OVER USB USING CDC DRIVER
Set both the scanner hardware/software handshaking settings described on pages 80 to 82 of this manual to None.
LS1203 Product Reference Guide - Zebra Technologies
Use PySerial to open and read the COM port assigned to the scanner.
If you scan the barcode with the scanner, you should be able to read the barcode data from the COM port.
This scanner is considered to be ready to read barcodes whenever the power is on.
The Enable/Disable function of reading does not appear to be published.
Based on the result report comment, the following options are considered.
Ask Zebra's support desk about whether or not it is possible.
Give up control in Python and use it in keyboard input emulation mode.
Give up the USB connection and use the RS232C connection cable.

How to stream data from MPU6050+NodeMCU to Raspberry Pi?

I'm working on a small project, trying to wirelessly stream Accelerometer and Gyro data from 5 MPU6050 to my Raspberry pi at 100Hz via wifi. I've managed to configure the NodeMCUs to sample the data from my accelerometers, but now I'm a little confused with how to get that data over to Pi.
Ideally, I want to have something similar to a "Serial Monitor" seen in the Arduino environment but instead on my Pi terminal window. As far as I understand, I need to set-up a "SERVER" on my pi and then connect NodeMCUs to it as "CLIENTs" (I've found this library: https://github.com/ekstrand/ESP8266wifi.
Does this make sense? If so, can someone point me in a "getting started" guide on how to set-up a server like that on Pi 3B?
Try this create a python script that will hit the web service where web service is the ip address of your nodemcu and from nodemcu send a JSON response parse the JSON response in your python script and display it.

Tornado on Raspberry Pi to use websockets as well as monitor serial port Arduino communication

Essentially, what I'm hoping to achieve is a canvas based web interface to control an Arduino, via a Raspberry Pi. The use case is that a user navigates to raspberrypi:8080 which displays a canvas. Then upon moving a slider, a websocket message is sent to the Tornado server on the Raspberry Pi. Tornado then sends a serial message to the Arduino which changes the RGB value of an LED. So far so good, I've been able to do this with the help of the documentation by a developer, Raspberry Pi Android HTML5 Realtime Servo Control.
However, the communication is only one-way from Raspberry Pi to Arduino. I'd like Tornado to also monitor the serial port to get any sensor data back to the front-end. Here's where I'm unsure about how to proceed. I was able to accomplish something like this using Node.js, which monitors for both websocket messages as well as serial messages asynchronously.
Should an asynchronous process be spawned which constantly monitors the port? I've seen a couple of options for this sort of solution.
Some people suggest tornado.gen.Task, but for single HTTP requests, not for constant serial data.
tornado.ioloop.PeriodicCallback which I could set up to check for serial data every millisecond, but that sounds like a lot of overhead.
I've also seen separate tools such as Swirl. (Swirl is outdated according to it's Github repo)
Or should I set up a separate Python application which monitors serial and then communicates to the Tornado application on something it can understand like the following?
websocket messages using a websocket client
ZeroMQ (working example: pyzmq / examples / eventloop / web.py)
So there are lots of options... What are some recommendations and some reasons to try out or avoid any of the above options?
Here's what I have and need to add serial monitoring to:
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket
from tornado.options import define, options
define("port", default=8080, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print 'new connection'
self.write_message("connected")
def on_message(self, message):
print 'message received %s' % message
self.write_message('message received %s' % message)
def on_close(self):
print 'connection closed'
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[
(r"/", IndexHandler),
(r"/ws", WebSocketHandler)
]
)
httpServer = tornado.httpserver.HTTPServer(app)
httpServer.listen(options.port)
print "Listening on port:", options.port
tornado.ioloop.IOLoop.instance().start()
Here are my 2 cents. I would advocate for the Python -> websockets-client route. The Tornado server software is made and tuned to handle web client requests. Let it do it's job. Any attempt to shoehorn it into another role (like monitoring local hardware) is going to cause more overhead than something which is either (a) designed to do such a job (like a C/C++ program) or (b) flexible enough to handle such a task with fairly little overhead (like a Python script).
Relevant Experience: Have programmed for both Raspberry Pi and Arduino. Officer in local robotics club.

Resources