从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 位整数

使用 Python 串行库处理从串口读取的原始数据?

Android + ESP32 通过蓝牙 (BLE) 发送数据

将参数从批处理文件发送到 Python 脚本

对于所有外键,如何在 SQL 中将数据类型从 32 位整数升级到 64 位整数?

如何从 Python 将无符号值发送到 dBus