第一篇文章,所以对我轻松一点。
我制作了一个python脚本,该脚本会截取当前显示的屏幕截图,并找到最经常出现的RGB颜色值。
我正在尝试通过串行将其发送到arduino pro micro(带有一些辅助组件)以驱动12v LED灯条。
我将各个红色,绿色和蓝色值进行位移,然后将它们加在一起成为一个无符号的32位整数,以发送到arduino,然后将使用位掩码,然后使用PWM引脚将其恢复为原始值在arduino上控制三个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条纹。
当连接arduino时,我使用Windows设备管理器中的硬件信息进行连接,因此python脚本肯定已连接至arduino,并且在脚本运行时,我无法使用其他任何东西来连接到arduino arduino。
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
答案 0 :(得分:0)
我已经在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);
}