ASCII communication using Pyserial - serial-port

I’m trying to send ASCII characters from an NVIDIA Jetson nano to a Roboteq motor controller. (MAX3232 to convert the logic level)
Using Pyserial for serial comm.
Sending 3 variable values for motor control, eg: ‘!VAR 1 250’ (‘!’ Is the start of the command)
Following is a snippet of the code,
import time
import serial
ser = serial.Serial(
port = '/dev/ttyTHS1',
baudrate = 115200,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
timeout = 1
)
command = ‘!VAR 1 250’ + ’ \r’
ser.write(command.encode())
data =
ser.readline().decode().strip()
print(data)
Coming to the issue,
‘!VAR 1 250’ does not pass the same value when sent every time.
Data string gets corrupted.
Is this because I am sending the ASCII command the wrong way? Is it being transferred in bytes?
I feel I am missing something here. How do we send an ASCII string via pyserial?

Related

STM32F415 Problems with I2C

I am using a STM32F415RGT6 embedded in the 1Bitsy Board. I want to set up the I2C Peripheral in order to read some data from a sensor. I am using the stm32f4 standard peripheral library.
My example code:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitTypeDef gpioInit;
GPIO_StructInit(&gpioInit);
gpioInit.GPIO_Mode = GPIO_Mode_AF;
gpioInit.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpioInit.GPIO_PuPd = GPIO_PuPd_UP;
gpioInit.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
GPIO_Init(GPIOB, &gpioInit);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1);
I2C_InitTypeDef I2C_InitStructure;
I2C_StructInit(&I2C_InitStructure);
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x01;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Generate Start, send the address and wait for ACK */
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, 0xE0, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
After that I want to write a 0x00, but the code always hangs in the last line, apparently the Master never reads the acknowledge. The I2C status registers always read:
I2C1 -> SR1 = 1024
I2C1 -> SR2 = 3
which means that the Acknowledge Failure bit is always set. If I analyze it using my Saleae I get the following:
The Slave sends the ACK, but the STM32F415 cannot read it.
The weird thing: If I try the same code on my F407 - Disco (only with clock set to 400khz, but it's the same behaviour on both MCUs regardless of Speed), it works flawlessly:
All other peripherals work fine. I already tried several workarounds, but the AF bit is always set, regardless of method. I hope you can help me.
P.S: I have tried with and without additional pullups and the I2C Slave Address is fine, because it works with STM32F0, STM32F4-DISCO and Atmel Mcus.
Best Regards and Thanks in advance!

Convert ASCII to Int

I'm using an Arduino for a project that involves controlling a servo via the serial monitor. The Arduino was receiving different values than what I entered. I'm sure that this is because serial data is read as ASCII. Is there any way that I could convert it to Int? Thanks!
I assume by Arduino you mean "Arduino IDE (C++)".
Arduino has a toInt() function.
int asciiVal = 97;
String mystr = (char)asciiVal;
Serial.println(mystr); //prints a
Serial.println(mystr.toInt()); //prints 97
Explained here: https://www.arduino.cc/en/Tutorial/StringToIntExample
Do it like this:
string input = Serial.readString();
int angle = int(input);
As I answered here.

How to read sensor data from Arduino in Raspberry Pi via Serial

for a school project I have to read data from 2 sensors on an Arduino (Sodaq Mbili) board. The sensors I use are TPHv2 (temperature, pressure, humidity) and a Grove Light Sensor. I want to read the temperature, humidity and light intensity. I use the following code for this:
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(bme.readTemperature());
Serial.println(bme.readHumidity());
int sensorValue = analogRead(SENSOR_PIN);
Serial.println(sensorValue);
delay(3000);
}
This gives me the following output every 3 seconds:
21.23
25.65
256
I then connect the Arduino to my Raspberry Pi 2 through USB.
I want to get the data in variables so that I can put it in a Json format and send it to an Azure Event Hub.
I now have this code in Python on the raspberry (I found this online):
import serial
ser = serial.Serial('/dev/ttyUSB0',9600)
s = [0]
while True:
s[0] = ser.readline()
print s
My output then gives, every 3 seconds:
['22.46\r\n']
['37.93\r\n']
['643\r\n']
My question now is, how do I get these 3 values in 3 different variables? I tried to put them in the same array (I want something like this: [22.46,37.93,643] ) but that didn't work.
Does anyone have suggestions? Thanks in advance!
Well, if you don't want to format the code in the arduino like jabujavi said, you could do something like this:
import serial
ser = serial.Serial('/dev/ttyUSB0',9600)
s = []
while True:
data = ser.readline() #read data from serial
if data: #if there is data, append it to s
s.append(data)
if len(s) == 3: #when s is 3 elements long, (all data has been retrieved)
print s #print out s
s = [] #and then reset s to start over.

My Qt app does not recieve all the data sent by arduino

I'll go right to the point. My arduino reads values from the adc port and send them via serial port(values from 0 to 255). I save them in a byte type vector. After sending an specific signal to arduino, it starts to send to Qt app the data saved in the vector. Everything is working except that the arduino should send 800 values and the app receives less values than that. If I set the serial baud rate to 9600, I get 220 values. If, instead, I set the baud rate to 115200, I get only 20 values. Can you guys help me to fix this? I would like to use 115200 baud rate, because I need a good trasmision speed at this project(Real time linear CCD). I'll leave some code below:
Arduino code:
void sendData(void)
{
int x;
for (x = 0; x < 800; ++x)
{
Serial.print(buffer[x]);
}
}
This is the function that sends the values. I think is enough information, so I summarized it. If you need more code, please let me know.
Qt serial port setting code:
...
// QDialog windows private variables and constants
QSerialPort serial;
QSerialPortInfo serialInfo;
QList<QSerialPortInfo> listaPuertos;
bool estadoPuerto;
bool dataAvailable;
const QSerialPort::BaudRate BAUDRATE = QSerialPort::Baud9600;
const QSerialPort::DataBits DATABITS = QSerialPort::Data8;
const QSerialPort::Parity PARITY = QSerialPort::NoParity;
const QSerialPort::StopBits STOPBITS = QSerialPort::OneStop;
const QSerialPort::FlowControl FLOWCONTROL = QSerialPort::NoFlowControl;
const int pixels = 800;
QVector<double> data;
unsigned int dataIndex;
QByteArray values;
double maximo;
...
// Signal and slot connection.
QObject::connect(&serial, SIGNAL(readyRead()), this,SLOT(fillDataBuffer()));
...
// Method called when there's data available to read at the serial port.
void Ventana::fillDataBuffer()
{
dataIndex++;
data.append(QString::fromStdString(serial.readAll().toStdString()).toDouble());
if(data.at(dataIndex-1) > maximo) maximo = data.at(dataIndex-1);
/* The following qDebug is the one I use to test the recieved values,
* where I check that values. */
qDebug() << data.at(dataIndex-1);
}
Thanks and sorry if it's not so clear, it has been an exhausting day :P
Ok... I see two probelms here:
Arduino side: you send your data in a decimal form (so x = 100 will be sent as 3 characters - 1, 0 and 0. You have no delimiter between your data, so how your receiver will know that it received value 100 not three values 1, 0 and 0? Please see my answer here for further explanation on how to send ADC data from Arduino.
QT side: There is no guarantee on the moment when readyRead() signal will be triggered. It may be immediately after first sample arrives, but it may be raised after there are already couple of samples inside the serial port buffer. If that happens, your method fillDataBuffer() may process string 12303402 instead of four separate strings 123, 0, 340 and 2, because between two buffer reads four samples arrived. The bigger the baudrate, the more samples will arrive between the reads, which is why you observe less values with a bigger baud rate.
Solution for both of your problems is to append some delimiting byte for your data, and split the string in the buffer on that delimiting byte. If you don't want to have maximum data throughput, you can just do
Serial.print(buffer[x]);
Serial.print('\n');
and then, split incoming string on \n character.
Thank you very much! I did what you said about my arduino program and after solving that, I was still not getting the entire amount of data. So the the problem was in Qt. How you perfectly explain, the serial buffer was accumulating the values too fast, so the slot function "fillDataBuffer()" was too slow to process the arriving data. I simplified that function:
void Ventana::fillDataBuffer()
{
dataIndex++;
buffer.append(serial.readAll());
}
After saving all the values in the QByteArray buffer, I process the data separately.
Thanks again man. Your answer was really helpful.

serial interfacing of 89s52 with Hyperterminal... getting garbage values

I need to transfer data serially from AT89s52 to Hyperterminal of PC.
For that I made a sample program to print "Hello" on the hyperterminal of my PC by programming the below given code inside 89s52 microcontroller and connecting it to my PC via serial port. Now when I am opening hyperterminal for the respective port, I should be seeing "Hello" printed on the screen multiple times, but what actually I am seeing is some garbage data getting printed.
This is the code I have used.
#include < AT89X52.H>
#include < STDLIB.H>
#include < STDIO.H>
unsigned int i;
void main (void)
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
TI = 1;
P1 = 0;
while (1)
{
puts("Hello\r");
P1 ^= 0x01; /* Toggle P1.0 each time we print */
for(i=0;i<25000;i++);
}
}
In the Hyper terminal I am not getting correct output i.e. Hello. Instead I am seeing some Garbage characters..
Can anybody help on this please..?
Can you See P1 is toggling? I would rather send a single character first and observe what is sending by using an oscilloscope. You should see a digital signal corresponding to the ASCII value of the character being split-out from the TX pin of the micro. Also you can check the baud rate (exact value) by using the scope. If you are convinced that the correct value is sent at the right baud rate it is most likely that you got a bad connection or perhaps the baud rate should slightly be changed.

Resources