I need to read 2 different bytes from TTP229 (16 keys or 8 keys touch pad detector).
I use I2C In Python. TTP229 datasheet PDF.
I can't read the second byte, but I can get the first byte.
Python code:
import smbus
bus = smbus.SMBus(1)
adressTTP229 = 0x57 #0xAF>>1
byte1 = bus.read_byte(adressTTP229)
byte2 = bus.read_byte(adressTTP229)
byte1 is always equal to byte2.
This Arduino code, works ok:
#include <Wire.h>
#define ttp229 (0xAF>>1)
void setup() {
Serial.begin(9600); // start serial for output
Wire.begin();
}
void loop() {
delay(50);
bool isNewData = false;
Wire.requestFrom(ttp229,2,true);
while (Wire.available()) {
uint16_t b1 = Wire.read(); // receive a first byte
uint16_t b2 = Wire.read(); // receive a second byte
if (b1==b2 && b2==0) {break;}
//...
}
}
How do I use Arduino's requestFrom() function in Python?
try:
import smbus, time
bus = smbus.SMBus(1)
while True:
print bus.read_word(0xAF)
time.sleep(0.1)
dont change address, bus doe the conversion, and if you read byte you will always get the same first byte. you want to read a word = 2 bytes at once
not tested, but might work, have it ordered and will test
Related
I'm trying to send a set of [x, y] coordinates from python to arduino in order to control servo motors on a robot drivetrain. I'm taking the approach of sending a string in the format "x,y". On the arduino side, I'm trying to parse this string to get the x and y substrings. However the indexOf function doesn't return the proper index. Here is my code:
arduino = serial.Serial(port='COM3', baudrate=9600, timeout=.1)
def write_read(x):
arduino.write(bytes(x, 'utf-8'))
time.sleep(0.05)
data = arduino.readline()
return data
for coordinate in coordinates:
c = str(coordinate[0]) + ", " + str(coordinate[1])
print(write_read(c))
#include <Servo.h>
void setup() {
Serial.begin(9600);
Serial.setTimeout(1);
}
void loop() {
while (!Serial.available());
String coordinates = "" + Serial.readString();
// Serial.print(coordinates); //this prints normally as the string value
int i = coordinates.indexOf(',');
Serial.print(i);
}
When I send something like "-9.45, -16.3". The output is b'-1-1-1-1-10-1-1-1-1-1-1'. I'm not sure what's going on here or how to get the actual index (in this case it would be 5).
import serial
ser= serial.Serial('com5',9600)
while 1:
Value_from_arduino = ser.readline()
Zustand = float(Value_from_arduino)
print(Zustand)
if Zustand == 1:
ser.write(0)
print('off')
elif Zustand == 0:
ser.write(1)
print(on)
This was the Python code, now here the arduino code.
char serialData;
int pin=12;
int pin2 = 5;
int Value;
void setup(){
pinMode(pin,OUTPUT);
pinMode(pin2,INPUT);
Serial.begin(9600);
}
void loop(){
Value = digitalRead(pin2);
Serial.println(Value);
delay(250);
while(Serial.available()){
serialData = Serial.read();
Serial.print(serialData);
if(serialData = '1'){
digitalWrite(pin,HIGH);
}
else if(serialData = '0'){
digitalWrite(pin,LOW);
}
}
}
My problem is, when i run my python code, it stops when he gets the Value 0 from my arduino.
Here is the report from python:
Zustand = float(Value_from_Arduino)
ValueError: could not convert string to float: b'\x000\r\n'
Python immediatly stops, but he puts the LED on.
The LED should be on if Python gets the value of 0, he do but then he just end run.
The LED should go on if value is 0 and of if value is 1.
You need to decode the serial bytes from the serial port.
Replace the Zustand = line in your code
Value_from_arduino = ser.readline()
Zustand = float(ser_bytes[0:len(Value_from_arduino )-2].decode("utf-8"))
Please check here https://makersportal.com/blog/2018/2/25/python-datalogger-reading-the-serial-output-from-arduino-to-analyze-data-using-pyserial
also try, if encodings doesn't work well
import struct
Zustand, = struct.unpack('<f',Value_from_arduino )
Finally i have found out please replace these lines of code
Steps -> Read,Decode to string, Strip /n and /r, Convert to float
please check here https://problemsolvingwithpython.com/11-Python-and-External-Hardware/11.04-Reading-a-Sensor-with-Python/
Value_from_arduino = ser.readline()
Value_from_arduino = Value_from_arduino.decode()
Value_from_arduino = Value_from_arduino.rstrip()
Zustand = float(Value_from_arduino)
Hope this Works..
In a project of mine, I have to take a picture from a camera connected to a Sony Spresense Arduino board which is linked to my computer via an USB port. I am not very experienced in Arduino and serial communication, not at all in fact, so I am asking for some help.
I want to read the data from the camera which is sent in hexadecimal from the Arduino to my computer via a Serial.begin at a given baud rate, processed by a Python program in order to collect the hex code, correct it (there have been some print errors which are now solved), and convert it to a JPEG image.
I am able to do it, but the serial communication part of my program where Python collects the data from the Arduino is significantly slow, it takes 34 seconds to obtain an image that weighs "only" 100 ko (I don't know if it's a lot to handle for an Arduino), at a baud rate of 115200. If I try to increase this number, the hex code collected shows some errors and the image can not be converted. I can also change the pixel resolution of the image, but I'd like to be able to work with HD pictures.
In detail, here is the code from the Arduino, I have found no other way than this to get the data from the camera (there is no designed function in the Spresense library for serial communication). The relevant part is at the end :
#include <SDHCI.h>
#include <stdio.h> /* for sprintf */
#include <Camera.h>
#define BAUDRATE (115200)
/**
* Print error message
*/
void printError(enum CamErr err)
{
Serial.print("Error: ");
switch (err)
{
case CAM_ERR_NO_DEVICE:
Serial.println("No Device");
break;
case CAM_ERR_ILLEGAL_DEVERR:
Serial.println("Illegal device error");
break;
case CAM_ERR_ALREADY_INITIALIZED:
Serial.println("Already initialized");
break;
case CAM_ERR_NOT_INITIALIZED:
Serial.println("Not initialized");
break;
case CAM_ERR_NOT_STILL_INITIALIZED:
Serial.println("Still picture not initialized");
break;
case CAM_ERR_CANT_CREATE_THREAD:
Serial.println("Failed to create thread");
break;
case CAM_ERR_INVALID_PARAM:
Serial.println("Invalid parameter");
break;
case CAM_ERR_NO_MEMORY:
Serial.println("No memory");
break;
case CAM_ERR_USR_INUSED:
Serial.println("Buffer already in use");
break;
case CAM_ERR_NOT_PERMITTED:
Serial.println("Operation not permitted");
break;
default:
break;
}
}
void CamCB(CamImage img)
{
/* Check the img instance is available or not. */
if (img.isAvailable())
{
/* If you want RGB565 data, convert image data format to RGB565 */
img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565);
}
else
{
Serial.print("Failed to get video stream image\n");
}
}
/**
* #brief Initialize camera
*/
void setup()
{
CamErr err;
/* Open serial communications and wait for port to open */
Serial.begin(BAUDRATE);
while (!Serial)
{
; /* wait for serial port to connect. Needed for native USB port only */
}
/* begin() without parameters means that
* number of buffers = 1, 30FPS, QVGA, YUV 4:2:2 format */
Serial.println("Prepare camera");
err = theCamera.begin();
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/* Start video stream.
* If received video stream data from camera device,
* camera library call CamCB.
*/
Serial.println("Start streaming");
err = theCamera.startStreaming(true, CamCB);
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/* Auto white balance configuration */
// Serial.println("Set Auto white balance parameter");
err = theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/* Set parameters about still picture.
* In the following case, QUADVGA and JPEG.
*/
Serial.println("Set still picture format");
// err = theCamera.setStillPictureImageFormat(
// CAM_IMGSIZE_QUADVGA_H,
// CAM_IMGSIZE_QUADVGA_V,
// CAM_IMAGE_PIX_FMT_JPG);
//err = theCamera.setStillPictureImageFormat(320, 240, CAM_IMAGE_PIX_FMT_JPG);
err = theCamera.setStillPictureImageFormat(CAM_IMGSIZE_QUADVGA_H, CAM_IMGSIZE_QUADVGA_V, CAM_IMAGE_PIX_FMT_JPG);
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/**
* #brief Take picture with format JPEG per second
*/
/******** Affichage serie ********/
/* une ligne de vide et l'image */
Serial.println(" ");
CamImage img = theCamera.takePicture();
/* Check availability of the img instance. */
/* If any error was occured, the img is not available. */
if (img.isAvailable())
{
/*Indicateur de debut img : FFD8FF (Magic number of the jpeg format) */
for(int i=0;i<img.getImgSize();i++)
{
Serial.print(*(img.getImgBuff()+i),HEX); //img.getImgBuff() gets the data address of the picture, so the * before.
Serial.print(";");
}
/*End indicator : FFD9FF (Magic number of jpeg format) */
}
}
void loop()
{
// put your main code here, to run repeatedly:
sleep(1);
}
And here is the Python code :
## Serial collecting the data of the picture taken by the camera
import serial
from serial import Serial
import binascii
import string
from PIL import Image
import time
start_time = time.time()
ser = serial.Serial('COM3', baudrate=115200, timeout=1)
# writing the data in a text file
data = open("data.txt", "w")
data.write(str(ser.readlines()))
## Correcting the data
data = open("data.txt", "r")
string = str(data.readlines())
# spliting the string into a list
# I chose to use the ";" to split the different hex couples in the Arduino program
tab=string.split(";")
tab[0] = 'FF'
tab.pop(-1)
N = len(tab)
# correcting the arguments that are not couples :
# Indeed, when Arduino encounter a couple starting with a 0,
# it omits it, so I have to add it back manually
for i in range(N):
if len(tab[i]) == 1:
tab[i] = '0' + tab[i]
newdata = open("newdata.txt", "w")
# writing the new data in a text file
for s in tab:
newdata.write(s)
newdata.close()
data.close()
## Converting the hex data into a JPEG file
file = open("newdata.txt", "r")
data= file.read()
# conversion
data = binascii.a2b_hex(data)
# creation of the JPEG file
with open('imagenew.jpg', 'wb') as image_file:
image_file.write(data)
file.close()
img = Image.open('imagenew.jpg')
img.show()
print("--- %s seconds ---" % (time.time() - start_time))
If you have any idea or any advice in order to speed up this process I am taking it. I heard that there are some flow control and buffer stories here and there, but I am quite lost when I try to find something relevant to my situation. Thanks in advance.
I use bpf from the python bcc module, and I want that my probe function will print the file path of the current file (kind of a custom simplified opensnoop).
How can I do that?
This is what I have so far:
b = BPF(text="""
#include <linux/ptrace.h>
#include<linux/sched.h>
BPF_HASH(last);
int trace_entry(struct pt_regs *ctx)
{
char fileName[200] = {0};
bpf_probe_read(fileName, sizeof(fileName), &PT_REGS_PARM1(ctx));
bpf_trace_printk("File Opened<%s>\\n", fileName);
return 0;
}
""")
print("Tracing for open... Ctrl-C to end")
b.attach_kprobe(event="do_sys_open", fn_name="trace_entry")
#b.attach_kprobe(event=b.get_syscall_fnname("open"), fn_name='funcky')
b.trace_print()
Easy:
Insert this in kernel code:
// Nicer way to call bpf_trace_printk()
#define bpf_custom_printk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})
struct pair {
uint32_t lip; // local IP
uint32_t rip; // remote IP
};
and in kernel code insert print out code. This function call works exactly like printf with all format and placeholder ...
bpf_custom_printk("This year is %d\n", 2020);
Print output:
sudo cat /sys/kernel/debug/tracing/trace_pipe
I have strings being continuously sent from my arduino.
For example, I am sending an integer (0-1023) line by line, so it should be:
"51\r\n233\r\n37\r\n166\r\n"
And infinitely long as it is continuously streaming.
I am currently using pyserial's function readline() to read the data, but constantly see broken/missing bytes. For example, instead of "37\r\n" followed with "11\r\n", it will get "3\r11\r\n" or even "3711\r\n"!
Here's my full Python-end code:
import serial
import time
if __name__ == '__main__':
ser = serial.Serial('COM3', baudrate=1000000)
data = []
time0 = time.time()
while (time.time() - time0 < 5): # Read data for 5 seconds
data.append(ser.readline())
ser.close()
For those interested, the (probably relevant) arduino code is simply:
#define FASTADC 1 // Flag for prescale 16
// Code pasted for modifying ADCSRA
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup() {
Serial.begin(1000000);
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
}
void loop() {
int val;
val = analogRead(A0);
Serial.println(val);
}
As you can see from the code, the baud rate, parity, stop bit were both set to 1,000,000; None; 1.