RS232 with raspberry pi - python

My issue is to make a serial communication between raspberry pi and another hardware. The recommended connection for this hardware is as shown on the manual, I have to connect, RX, TX, GND, RS, and CS.
But on raspberry pi we have only RX, TX so I connected RX and TX and The GNG of Pi to this hardware.
I modified Pi's parameters as shown on the link : here
Then I maked a simple python program that initialize the communication, and send data.
Here is the code :
import serial,os
port=serial.Serial("/dev/ttyAMA0",baudrate=9600)
print ('port is ok')
port.write('Command')
rcv=port.read(10)
print rcv
after running this code on pi, I got ('port is ok'), But the problem is that this hardware don't respond correctly to the command, and as respoce it gave me normally OK, but I got some extra caracter( non readable).
Is that a problem of encoding? Can some one help about this?

You need to check the baud rate on the other hardware
or make sure that the length of the received message = to the printed message.

In a serial communication, there are two important things to be careful :
The two devices have to work with the same baudrate IF the link is bidirectional.
When writing data on serial, you have to flush data just after the write().
refer to here for it.
In a lot of case, flush isn't needed, but when two different devices have to communicate, it could unlock the comm'.
If it's not efficient, try to set up your other device with the same conf (no flow control, etc)

Related

How can I push a file out to multiple Raspberry Pi Pico's at once?

I am looking for a DIY replacement for the $1500 Go-Box for mass provisioning Chromebooks. I have managed to replicate this by using a Raspberry Pi Pico as the "HID Emulation". However, I need this on a mass scale. I want to be able to do 20 Chromebooks at one time. I can do this with just 20 Raspberry Pi Picos but I need to change the script every 100-150 Chromebooks I provision (changing credentials etc.). Changing each script manually is time-consuming, so I need to be able to change all 20 scripts at once, or one "master" script that the "slave" Picos go and get on boot.
At first, I thought about an SD card they can all read from and when needed, I can take it out and change the script on there, and then when the Pico boots it can copy the new script to the root of the Pico. However, this may be an issue since I do not know if the Picos will clash with each other when trying to read the script from the same place at the same time. This is my first issue.
Then I thought about a Master and Slaves setup. One Pico acts as a Master and holds the script. The other 20 are slaves that get the script from the Master when a pin is high (to signify the Picos need reprogramming). I would only use the Master when reprogramming the script. When I turn the Master on, I would have it set a pin to high and all the other slaves would check on the boot to see if the pin is high. If the Slaves find that the pin is high, it won't run the script, but it will update it from the Master. This is where I run into the problem with this method. I need to transfer the script from Master to Slaves. I haven't got any experience in communication protocols like UART, SPI, or I2C but I understand that if I want to do multiple Slaves, then I am better off using I2C.
This is my last resort since I have been googling for days and can't find a suitable solution. Is anyone able to provide any insight on any of the following:
How to get the script from one place to twenty?
Will the SD card idea clash when all 20 Picos try to access it?
How to transfer files over I2C or similar protocol?
I appreciate any help anyone can provide. I am using MicroPython v1.16 on 2021-06-18; Raspberry Pi Pico with RP2040
The pico has a uart (2 actually) which is easy to program; there are lots of examples of serial communication with the pico, typically to a full Raspberry Pi.
You could join all the rx receiver pins on the picos to the master tx transmit pin and talk to them all in parallel, with no replies.
I don't know if it is possible to tri-state the tx pins so that they could all be connected too, but only one enabled at a time, by sending suitable commands from the master tx. The problem is that the electrical load of 20 receivers, and the excessive length of the parallel cabling might not give error free transfers.
Or you could daisy chain the serial ports so the rx of pico1 is read by the software there and repeated out on its tx, which is connected to the rx of pico2, and so on. You can start each data packet with a "node number", which each pico decrements before sending it on. If this number is 1, then the packet appplies to this node. This is a sort of auto-numbering of the picos. A number like 255 can be used for a broadcast.
If the last pico's tx is wired back to the master you can even allow any pico to send a reply, provided the software waits for a break in incoming data.
It also allow for rudimentary flow control and error checking. If the master sends only 1 byte at a time, and waits for each byte to be "echoed" back from the last pico, it can ensure everyone has seen the data. Also, each serial segment can be short so there are no electrical load problems, or signal corruption.
Look at the gpib bus which daisy chains something like this, or at the simple individually-addressible RGB leds like the WS2812B which are also daisy chained.

Directly send signals to USB using Python

How can I set HIGH or LOW to a usb port connections using Python.
This could be used in come custom usb device.
For Example,
Consider I have a LED connected to the usb port(DATA Line) .
Now through the code I want to blink it or control it.
Now this can be easily achieved by using any micro controller, Arduino, Raspberry Pi
But I want to achieve this with with a normal computer and python.
[EDIT]
Can I achieve this by making a C or C++ API and make a wrapper to use it in Python. Is yes then what will be the best way to achieve it?
NOTE :
My main objective isn't just blinking some LED. I just gave it as an example.
I want to be able to directly control the USB ports.
Quoting : https://www.cmd-ltd.com/advice-centre/usb-chargers-and-power-modules/usb-and-power-module-product-help/usb-data-transfer-guide/#:~:text=How%20is%20data%20sent%20across,amounts%20known%20as%20'packets'.
Within the standard USB 2.0 connector you can see four metal strips. The outer two strips are the positive and ground of the power supply. The two central strips are dedicated to carrying data.
With the newer USB 3.0 connector, the data transfer speed is increased by the addition of extra data-carrying strips; four extra signalling wires help USB 3.0 achieve its super speed.
I want to set the values of the Data pins.
By my saying HIGH LOW please don't misunderstand that I want to set the value to +5V and GND. But I mean to control its value directly via my code without any external driver present in the computer.
I mentioned HIGH LOW to just make the language simple and so that it is easier to understand.
Controlling components like LEDs from devices like Arduino and Raspberry Pi are done using GPIO pins. In contrast, USB is designed for data transfer and not for maintaining more constant high or low signals like GPIO. It also consumes different voltage and current levels than GPIO pins and could potentially damage components meant for GPIO.
However, you can get USB to GPIO adapters for this purpose (see here for an example discussion on these options).
In terms of Python, you can use packages such as PyUSB or the libusb Python wrapper to control/transfer data/communicate with USB devices (such as the USB to GPIO adapters). The companies providing the adapters might also have designed their own easy-to-use Python package to wrap around a lower-level driver (probably written in C). See this USB controlled LED device as an example with its own Python driver. The drivers are just software programs that take in relatively simple commands from the user for what they want a device to do. They then encapsulate the lower-level complexities required for following a protocol to communicate the user's intention to the USB device and controlling the USB port at the lowest possible software level.
You cannot achieve that for several reasons:
The USB port has its own protocol of connection. Data is transmitted in packets with starting and ending bits. The negotiation and handshake process is done in the hardware layer between microchips. This process also selects the communication speed in the bidirectional data line. You have to direct access to the pin (like GPIO) to turn LEDs ON and Off or create your own connection protocol. This cannot be done in USB.
There are also voltage and current limitations. The data line is not +5 and GND. The data line is 2.8v for D+ and 0.3v for D- and both with respect to the GND. The data is transmitted and received differentially (D+ with respect to D-) and they are not compared with the GND for 1s and 0s.
The button line is you have no direct control over USB.

Transmit consecutively using I2C on Raspberry Pi, python smbus

I want to transmit AVR or Arduino etc by I2C from Raspberry pi.
I am writing in Python.
I already successeded communication using write_data() function in smbus module.
But I want to transmit multiple bytes data consecutively.
Please tell me how to transmit multiple bytes data in i2c communication.
I find write_block_data() function, but I don't understand the second parameter CMD.
What is the CMD?? Should I specify the value of CMD?
thank you.
Communicating between an RPi and an Arduino on I2C is a big mess if you are using Wire.h library. The short answer is that RPi is using a repetitive start signal while Arduino is not using it.
Repetitive start signal on I2C interface tells the slave to start answering for the call. In case of the Arduino asking and answering is in two separated calls. Therefore you cannot send block
I made two blog posts to interface the two architecture through I2C. First one is for using a remote controller PWM: http://distantorion.com/2014/10/24/rc-signals-pwm-to-i2c-with-arduino/
The second one is for driving a 128x64 LCD display on I2C: http://distantorion.com/2014/11/01/i2c-display-with-arduino/
In the second one I'm using block data in python:
bus.write_i2c_block_data(0x05,0x10,buff)
0x05 is the device address, 0x10 is the "command", buff containd the characters to display.
Regarding the commands. In I2C a slave works in a way of commands or registers. Both method looks like the same. If you are using a repetitive start signal the communication seems to be reading and writing registers. When you have no repetitive start signal, the communication looks like a command - answer system. In my example I'm sending 0x10 what is "put the characters from to the display". And 0x01 is a clear screen command, while 0x02 turns on the backlight.

Program execution stopping on atml atmega16 microcontroller upon terminal connection

I am attempting to receive data from the qu-bot at http://www.qu-bot.com. The robot has an ATML atmega16 microcontroller. I have written a program that runs on the robot which outputs data to its serial port. The program however stops whenever I connect to the controller. I tested this by adding a beep statement. The robot beeps as long as the program is running. The beeping stops when I connect to the robot. I tried qu-bo support and they suggested disabling the dtr flag on the serial port. I did that but no joy.
Is there anything else I can try?
[start of code running on the qu-bot]
Note:
This is written in some kind of proprietary variant of C which they call quick c.
// This code displays the uart functions.
int main(void)
{
INIT();
UART_INIT(57600);
UART_PRINT("HELLO!!\n");
DELAYS(1);
UART_PRINT("MY NAME IS QU-BOT.\n");
DELAYS(1);
UART_PRINT("HELLO!!\n");
UART_PRINT("YOU ARE USING UART SAMPLE CODES.\n");
while(1)
{
UART_PRINT("test\n");
BEEP();
DELAYS(60);
}
}
now for my python serial port reading program. I have tried this program both on raspbian and on windows 7 64bit. I am pasting the windows version. The raspbian version has a different name for the linux.
import serial
import time
ser=serial.Serial()
ser.port=8
ser.baudrate=57600
ser.setDsrDtr(False)
print 'initialized'
flag = ser.isOpen()
if flag:
print 'port already open.'
pass
else:
ser.open() # opening the port 'ser' that was just created to receive data
time.sleep(0.5)
print 'ready to read'
print ser
ser.write('a')
s=ser.read(4)
print s
ser.close()
Pranav
P.S. I have consulted the following links amongst others.
<https://learn.sparkfun.com/tutorials/terminal-basics/all>
<http://www.plainlystated.com/2013/06/raspberry-pi-serial-console/>
<http://elinux.org/RPi_Serial_Connection>
<https://learn.sparkfun.com/tutorials/terminal-basics/all>
Based on my experience in serial communications with microcontrollers the most likely cause of this problem is that when you connect the serial cable to the robot it causes a phantom byte (due to electrical noise that happens when you make the connection) to look like it's coming from the controller - either this or the controller is sending a legitimate byte to the robot. In either case it is likely that the arrival of a byte at the robot's serial port (even if it was only electrical noise mistaken to be a data byte - this is a very common occurrence) caused the robot's microcontroller to invoke the UART receive interrupt. If you don't have an appropriate UART receive handler (ISR - Interrupt Service Routine) written and linked into the correct interrupt vector then your robot's microcontroller can go off into "deep space" upon the detection of the first incoming serial data byte - and make your robot appear to "hang". If you intend to do "polled" serial communications (your code manually checks for received bytes in its main loop) instead of interrupt-driven (hardware detection of an incoming byte causes your UART Rx ISR to be invoked) then all you have to do is to disable UART interrupts and your problem should go away.

Pyserial problem with Arduino - works with the Python shell but not in a program

All right, so I am positive my Arduino circuit is correct and the code for it. I know this because when I use the serial monitor built into the Arduino IDE and send 'H' an LED lights up, when I send 'L' that LED turns off.
Now I made a Python program
import serial
ser = serial.Serial("COM4",9600)
ser.write("H")
When I run the code the LED blinks on for a second then goes back off.
However when I do each of these lines separately in the shell it works just like it is supposed to.
Any ideas?
When you open the serial port, this causes the Arduino to reset. Since the Arduino takes some time to bootup, all the input goes to the bitbucket (or probably to the bootloader which does god knows what with it). If you insert a sleep, you wait for the Arduino to come up so your serial code. This is why it works interactively; you were waiting the 1.5 seconds needed for the software to come up.
I confirmed that opening the serial port resets my Arduino Uno; I flashed a program which will blink the LED from the setup() routine -- calling open("/dev/ttyACM0") was sufficient to trigger the reset. This is IMHO a confusing and undocumented wrinkle in the serial support.
I had the same problem and it works if I add a delay of about 2 seconds from opening the serial connection to writing on it, 1 second was not enough.
Just to make it a bit more clear I'll modify the code so everyone can see what needs to be added!
import serial
import time
ser = serial.Serial("COM4",9600)
time.sleep(3)
ser.write("H")
Adding in a sleep statment helps to let the serial open up without any problems!
Assuming you are using an Arduino Uno
The USB port and the Uno serial bus exposed on pins 1 and 0 share the same RX/TX lines. I suggest getting a USB to TTL adapter like the one here so that you can communicate to the Arduino without using the USB port. The Arduino IDE has its own method for disengaging from the USB driver such that a virtual serial port can be created. Have your Ardunio use SoftwareSerial instead.
Here is an example I found on the internet where somebody had clashing bus issues.

Categories