Отправка 32-битного целого числа из скрипта Python в Arduino через последовательный порт для использования в управлении полосой RGB - PullRequest
0 голосов
/ 13 апреля 2019

первый пост, так что будь осторожен со мной.

Я создал скрипт на python, который делает снимок текущего экрана и находит наиболее часто появляющееся значение цвета RGB.

Я пытаюсь отправить это через последовательный порт на Arduino Pro Micro (с некоторыми дополнительными компонентами) для управления светодиодной полосой 12 В.

Я сдвигаю по битам отдельные значения красного, зеленого и синего цветов и добавляю их вместе в 32-разрядное целое число без знака для отправки в arduino, который затем использует битовую маску, чтобы затем вернуть исходные значенияс помощью выводов ШИМ на контроллере Arduino три МОП-транзистора (N-канал) для управления отдельными цветами на полосе RGB.Каждый цвет имеет 256 значений, поэтому может быть представлен в 8 битах, показанных ниже.

32-битный без знака int

неиспользуемый синий зеленый красный

00000000 00000000 00000000 00000000

красная маска

00000000 00000000 00000000 11111111

зеленая маска

00000000 00000000 11111111 00000000

синяя маска

00000000 11111111 00000000 00000000

Моя проблема в том, что последовательная связь между скриптом Python и Arduino, похоже, не работает, и я не могу понять, почему.Это как-то связано с форматом 32-разрядного целого числа без знака, которое я посылаю?На самом деле я не нахожу никакой информации о приемлемых форматах и ​​имею небольшой опыт использования последовательной связи.

Что я знаю, так это то, что схема Arduino определенно правильно подключена, так как я могу полностью управлять полосой RGB, указав значенияна стороне Arduino.

Сценарий python определенно подключается к arduino, так как я подключаюсь, используя информацию об оборудовании, найденную в диспетчере устройств Windows, когда подключено arduino, и во время работы сценария я не могу использовать что-либо еще для подключения к COM-портуиспользуется 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

1 Ответ

0 голосов
/ 14 апреля 2019

Я написал и протестировал свое решение для разбавленной связи для вашего случая на 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...