从python脚本发送32位整数到串行的arduino,用于驱动RGB条带
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从python脚本发送32位整数到串行的arduino,用于驱动RGB条带相关的知识,希望对你有一定的参考价值。
第一篇帖子对我来说很容易。
我制作了一个python脚本,它截取当前显示的截图并找到最常出现的RGB颜色值。
我试图通过串口发送到arduino pro micro(带有一些辅助组件)来驱动12v LED灯条。
我将各个红色,绿色和蓝色值进行位移,并将它们一起添加到一个无符号的32位整数中,然后发送到arduino,然后使用位掩码然后使用arduino上的PWM引脚返回原始值。控制三个MOSFET(N通道)以驱动RGB条带上的各种颜色。每种颜色都有256个值,因此可以用下面的8位表示。
32位无符号整数
未使用的蓝绿红
00000000 00000000 00000000 00000000
红色面具
00000000 00000000 00000000 11111111
绿色面具
00000000 00000000 11111111 00000000
蓝色面具
00000000 11111111 00000000 00000000
我的问题是python脚本和arduino之间的串行通信似乎没有起作用,我无法弄清楚原因。这与我发送的无符号32位整数的格式有关吗?我并没有真正找到有关可接受格式的信息,也没有使用串行通信的经验。
我所知道的是arduino电路肯定是正确连接的,因为我可以通过指定arduino侧的值来完全驱动RGB条带。
python脚本肯定连接到arduino,因为当连接arduino时,我使用windows设备管理器中的硬件信息进行连接,并且当脚本运行时,我无法使用任何其他东西连接到arduino使用的COM端口。
python脚本正在计算和格式化我想要的值,因为我可以简单地将它们打印到控制台而不是写入串行来确认。
from PIL import Image
import serial
import serial.tools.list_ports
import pyscreenshot as ImageGrab
import time
from collections import Counter
if __name__ == '__main__': ###main program###
# open comms with arduino
VID = "2341" #arduino pro micro HEX vendor ID given throught the arduino IDE
PID = "8037" #arduino pro micro HEX product ID given throught the arduino IDE
arduino_pro_micro_port = None
ports = list(serial.tools.list_ports.comports()) #get ports information
for port in ports:
if PID and VID in port.hwid: #look for matching PID and VID
arduino_pro_micro_port = port.device #serial port of arduino nano pro
if arduino_pro_micro_port == None:
print("Couldn't find an ardiuno pro micro to communicate with")
else:
COMPort = serial.Serial(arduino_pro_micro_port, 115200, writeTimeout = 0) #open connection for RGB values to be written
while True: #loop forever
image = ImageGrab.grab() #grab screenshot
image = image.resize((512, 288)) #20% size for faster processing
image = image.load() #load image so pixel information can be interrogated
RGBlist = []
#seperate pixel tuple into lists for red, green and blue
for horizontal in range(0, 512, 1): #for all horizontal pixels
for vertical in range(0, 288, 1): #for all vertical pixels
red = image[horizontal, vertical][0]
blue = image[horizontal, vertical][1] << 8
green = image[horizontal, vertical][2] << 16
RGBlist.append(red + green + blue)
sendLong = Counter(RGBlist).most_common(1)
print("send " + str(sendLong[0][0]))
COMPort.write(sendLong[0][0]) #write RGB to serial port
print("reci "+ str(COMPort.readline())) #read and print line from arduino
time.sleep(0.1) #wait 0.1 seconds
```end of python code
```arduino code
//set pin integers for RGB
int LEDRPin = 5;
int LEDGPin = 6;
int LEDBPin = 9;
//setup variable store for RGB values
unsigned long incomingLong = 0; //store the incomoing byte for processing#
unsigned long redMask = 255; //bitmask for red value
unsigned long greenMask = 65280; //bitmask for green value
unsigned long blueMask = 16711680; //bitmask for blue value
unsigned long Rv = 0; //red value will be stored here
unsigned long Gv = 0; //green value will be stored here
unsigned long Bv = 0; //blue value will be stored here
unsigned long SAVE_Rv = 0; //red value will be saved here
unsigned long SAVE_Gv = 0; //green value will be saved here
unsigned long SAVE_Bv = 0; //blue value will be saved here
void setup() {
//initialise RBG pins as outputs
pinMode(LEDRPin, OUTPUT);
pinMode(LEDGPin, OUTPUT);
pinMode(LEDBPin, OUTPUT);
//start serial comms
Serial.begin(115200);
if(Serial.available())// only send data back if data has been sent
{
incomingLong = Serial.read(); //read RGB values from serial port
Serial.write("Ready");
}
}
void loop() {
delay(300);
if(Serial.available() >= 0) // only send data back if data has been sent
{
incomingLong = Serial.read(); //read RGB values from serial port
Serial.write(incomingLong);
Rv = redMask & incomingLong; //get red value
Gv = greenMask & incomingLong; //get green value
Bv = blueMask & incomingLong; //get blue value
Rv = Rv >> 0; //shift to LSB
Gv = Gv >> 8; //shift to LSB
Bv = Bv >> 16; //shift to LSB
Rv = (int) Rv; //Cast to int
Gv = (int) Gv; //Cast to int
Bv = (int) Bv; //Cast to int
analogWrite(LEDRPin, Rv); //write red value to output pin
analogWrite(LEDGPin, Gv); //write green value to output pin
analogWrite(LEDBPin, Bv); //write blue value to output pin
SAVE_Rv = Rv;
SAVE_Gv = Gv;
SAVE_Bv = Bv;
}
}
```end of arduino code
我已经在python27和arduino Uno上为你的案例编写并测试了我的淡化通信解决方案但是应该给你或多或少相同的结果。测试它并让我知道你是否需要澄清或在某些时候陷入困境。
# python27
import serial
import serial.tools.list_ports
import struct
import sys
arduino_pro_micro_port = 'COM3'
COMPort = serial.Serial(arduino_pro_micro_port, 115200, writeTimeout = 0)
while True:
r = 12
g = 145
b = 87
if COMPort.in_waiting:
#COMPort.write(struct.pack("l", 123)) # sending one long directly
COMPort.write(struct.pack("BBB", r, g, b)) # B means unsigned byte
print COMPort.readline()
// Arduino
void setup() {
// put your setup code here, to run once:
//start serial comms
Serial.begin(115200);
Serial.println("Ready");
}
void loop() {
// I'm taking the delay off as that might cause synchronization issues on the receiver side
while (Serial.available() <= 3); // only send data back if data has been sent
int r = Serial.read(); //read RGB values from serial port
int g = Serial.read(); //read RGB values from serial port
int b = Serial.read(); //read RGB values from serial port
Serial.println("RGB: ");
Serial.println(r);
Serial.println(g);
Serial.println(b);
delay(3000);
}
以上是关于从python脚本发送32位整数到串行的arduino,用于驱动RGB条带的主要内容,如果未能解决你的问题,请参考以下文章
Python:如何将 32 位有符号长整数转换为 7 位整数
Android + ESP32 通过蓝牙 (BLE) 发送数据