![]() |
RGB Farbwerte an einen Mikrocontroller senden
Hallo liebe Delphi Gemeinde,
ich hoffe ihr könnt mir bei meinem Problem weiterhelfen und ich hoffe das Thema ist im richtigen Unterforum erstellt ;) Also mein Vorhaben ist einfach: In Delphi RGB-Farbwerte einstellen/ermitteln per ScrollBar oder Farbkreis, das ist auch kein Problem. Diese Daten dann als String an einen Mikrocontroller senden, dieser steuert dann eine RGB Leuchtdiode an (werden später mehr). Der Mikrocontroller ist ein Atmel ATMEGA328P fertig auf eine Platine gelötet als Arduino und hängt am USB. Für den Arduino habe ich auch schon einen fertigen Code aus dem Internet, dieser funktioniert leider nur mit dem Interface, das der Verfasser in Processing(Java) geschrieben hat. Ich möchte den Controller allerdings mit Delphi ansprechen. Ein einfaches 'L' um eine LED anzuschalten bzw. ein 'H' um sie auszuschalten konnte ich schon an den Controller senden. Mit TComport das hat der Arduino verstanden, aber wenn ich die dreistelligen RGB Werte sende geht irgendwas schief... Ich weiß echt nicht mehr weiter, habe leider auch nicht so viel Erfahrung mit sowas. Ca. 30 Stunden Internetsuche haben mein Problem nicht lösen können. Jetzt folg erstmal eine ganze Menge Code zur Verdeutlichung: Das ist erstmal der Processing Code, den der Andere benutzt hat, um RGB Farbwerte zu ermitteln und an den Arduino zu schicken: Das wichtigste im Code ist aber ganz unten hier nochmal extra:
Code:
myPort.write('L');
myPort.write(r); myPort.write(g); myPort.write(b);
Code:
Das hier ist der Code der auf dem Arduino die Werte empfängt und die Farbe an die RGB LED gibt:
import processing.serial.*;
Serial myPort; PFont font; int r = 0; int g = 0; int b = 0; void setup() { size(512, 512); println(Serial.list()); String portName = Serial.list()[1]; myPort = new Serial(this, portName, 9600); font = loadFont("AngsanaNew-Bold-48.vlw"); } void draw() { background(0, 0, 0); smooth(); stroke(50, 50, 50); fill(r, g, b); rectMode(CORNERS); rect(20, 20, width / 2 - 10, height - 20); textFont(font); textAlign(CENTER, TOP); text("COLOR!", width - width / 4 - 5, 20); textAlign(LEFT); fill(r, 0, 0); text("R: ", width - width / 2, 292); textAlign(RIGHT); text(r, width - 10, 292); textAlign(LEFT); fill(0, g, 0); text("G: ", width - width / 2, 392); textAlign(RIGHT); text(g, width - 10, 392); textAlign(LEFT); fill(0, 0, b); text("B: ", width - width / 2, 492); textAlign(RIGHT); text(b, width - 10, 492); g = mouseX / 2; b = mouseY / 2; if ((mousePressed == true) && (mouseButton == LEFT) && (r < 251)) { r += 5; } if ((mousePressed == true) && (mouseButton == RIGHT) && (r > 4)) { r -= 5; } myPort.write('L'); myPort.write(r); myPort.write(g); myPort.write(b); }
Code:
wichtig hierbei:
byte r = 0;
byte g = 0; byte b = 0; byte r_pin = 9; byte g_pin = 10; byte b_pin = 11; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() == 4) { if (Serial.read() == 'L') { r = Serial.read(); g = Serial.read(); b = Serial.read(); } } analogWrite(r_pin, r); analogWrite(g_pin, g); analogWrite(b_pin, b); }
Code:
So zu guter letzt der Delphi Code mit dem ich eigentlich das machen will, was der Processing Code macht:
Serial.begin(9600);
} void loop() { if (Serial.available() == 4) { if (Serial.read() == 'L') { r = Serial.read(); g = Serial.read(); b = Serial.read(); }
Delphi-Quellcode:
Sind einfach 3 ScrollBars an denen ich die Werte für R G B einstelle und dann diese an den Controller sende, was nicht funktioniert :(
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, CPortCtl, CPort, StdCtrls; type TForm1 = class(TForm) ComPort1: TComPort; ComDataPacket1: TComDataPacket; Button1: TButton; Button2: TButton; Button4: TButton; ScrollBar1: TScrollBar; ScrollBar2: TScrollBar; ScrollBar3: TScrollBar; Label1: TLabel; Label2: TLabel; Label3: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure ScrollBar1Change(Sender: TObject); procedure ScrollBar2Change(Sender: TObject); procedure ScrollBar3Change(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; r,g,b:integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin ComPort1.ShowSetupDialog; end; procedure TForm1.Button4Click(Sender: TObject); begin begin if ComPort1.Connected then ComPort1.Close else ComPort1.Open; end; end; procedure TForm1.ScrollBar1Change(Sender: TObject); begin r:=ScrollBar1.Position; Label1.Caption:=Inttostr(r); end; procedure TForm1.ScrollBar2Change(Sender: TObject); begin g:=ScrollBar2.Position; Label2.Caption:=Inttostr(g); end; procedure TForm1.ScrollBar3Change(Sender: TObject); begin b:=Scrollbar3.Position; Label3.Caption:=IntToStr(b); end; procedure TForm1.Button2Click(Sender: TObject); begin ComPort1.WriteStr('L'); ComPort1.WriteStr(Inttostr(r)); ComPort1.WriteStr(Inttostr(g)); ComPort1.WriteStr(Inttostr(b)); end; end. Ich hoffe irgendjemand kann mir weiterhelfen. Glaubt bitte nicht ich hätte es nicht selber versucht, aber bin relativ neu in Delphi, in einem anderem Forum, das sich aber eher mit Leuchtdioden beschäftigt meinte jemand es wäre vielleicht besser die Werte als Array zu schicken? Wie gesagt der Arduino Code geht der Fehler liegt halt daran wie die Daten in Delphi gesendet werden. Der Gedanke diesen Codebrocken einfach so nachzubauen ohne viel Aufwand, war leider ein Irrtum ;)
Code:
myPort.write('L');
myPort.write(r); myPort.write(g); myPort.write(b);
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin ComPort1.WriteStr('L'); ComPort1.WriteStr(Inttostr(r)); ComPort1.WriteStr(Inttostr(g)); ComPort1.WriteStr(Inttostr(b)); end; SRY für den Roman, und Danke schonmal. Hier nochmal der Link ins LED Forum wo ich auch schon nachgefragt hatte: ![]() EDIT: Achso ich verwende (leider) Delphi 7 ;) |
AW: RGB Farbwerte an einen Mikrocontroller senden
Ich vermute, dass da etwas Entscheidendes fehlt:
Der ARDUINO ist kein Hellseher. Woher soll er wissen, was er mit den empfangenen Daten machen soll? Wenn der ARDUINO 3 Bytes für RGB erwartet, dann musst Du auch 3 Bytes senden: R:=ScrollBar1.Position; G:=ScrollBar2.Position; B:=ScrollBar3.Position; ComPort1.SENDBYTE(76); // L= 76 ComPort1.SENDBYTE(R); ComPort1.SENDBYTE(G); ComPort1.SENDBYTE(B); Integerwerte kannst Du direkt senden ohne Umwandlung. Die OnChange-Proceduren kannst Du vereinfachen.
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SynaSer; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button4: TButton; ScrollBar1: TScrollBar; ScrollBar2: TScrollBar; ScrollBar3: TScrollBar; Label1: TLabel; Label2: TLabel; Label3: TLabel; procedure Button4Click(Sender: TObject); procedure ScrollBarChange(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; R,G,B: integer; implementation {$R *.dfm} procedure TForm1.Button4Click(Sender: TObject); var ser:TBlockSerial; begin ser:=TBlockSerial.Create; ser.RaiseExcept:= false;//True; try ser.Connect('COM1'); ser.Config(StrToIntDef('9600', 9600),8,'N',2,false,false); sleep(20); ser.SENDBYTE(76); // L= 76 ser.SENDBYTE(R); ser.SENDBYTE(G); ser.SENDBYTE(B); finally ser.Free; end; end; procedure TForm1.ScrollBarChange(Sender: TObject); //für alle 3 gleich begin Label1.Caption:=Inttostr(ScrollBar1.Position); Label2.Caption:=Inttostr(ScrollBar2.Position); Label3.Caption:=Inttostr(ScrollBar3.Position); R:=ScrollBar1.Position; G:=ScrollBar2.Position; B:=ScrollBar3.Position; Button4Click(Self); end; |
AW: RGB Farbwerte an einen Mikrocontroller senden
Code:
in die Variablen einfügen und dann an die Pins der RGB LED senden.
void loop() {
if (Serial.available() == 4) { if (Serial.read() == 'L') { r = Serial.read(); g = Serial.read(); b = Serial.read(); } } analogWrite(r_pin, r); analogWrite(g_pin, g); analogWrite(b_pin, b); } |
AW: RGB Farbwerte an einen Mikrocontroller senden
Delphi-Quellcode:
Beim Arduino kommt Folgendes an:
{*SNIP*}
ComPort1.WriteStr('L'); ComPort1.WriteStr(Inttostr(r)); ComPort1.WriteStr(Inttostr(g)); ComPort1.WriteStr(Inttostr(b)); {*SNIP*} "L<r><g><b>" (formatiert) Also wenn r = 50, g = 100, b = 150, dann würde das so aussehen: "L50100150" Weiß dein Arduino damit umzugehen? Ich würde da lieber noch ein "-" einbauen und im Arduino dann den String wieder in seine Einzelteile zerlegen! |
AW: RGB Farbwerte an einen Mikrocontroller senden
Delphi-Quellcode:
Datenübertragung muss natürlich auf 8-Bit eingestellt sein...
var
command : AnsiString; begin command := 'L'+Chr(Inttostr(r))+Chr(Inttostr(g))+Chr(Inttostr(b)); ComPort1.WriteStr(command); |
AW: RGB Farbwerte an einen Mikrocontroller senden
Zitat:
Delphi-Quellcode:
var
command : AnsiString; begin command := 'L'+Chr(r)+Chr(g)+Chr(b); ComPort1.WriteStr(command); |
AW: RGB Farbwerte an einen Mikrocontroller senden
Vielen Dank erstmal, probiere es gleich mal aus, ja der Arduino Code ist nicht so toll, habe den Arduino erst seit Freitag und seit dem ziemlich viel Zeit damit verbracht zu verstehen, aber habe es leider bis jetzt nicht hinbekommen einen String anständig zu zerlegen.
Darum habe ich erstmal einen Code genommen der schon da war. Aber besser wäre natürlich wenn ich z.B. R255G255B255; oder so etwas schicke, aber da fehlt halt noch das know how Super das mir so schnell geholfen wird hier, habe so viel in allen möglichen Foren gelesen in den letzten Tagen, auch einiges gelernt, aber geholfen hat es nicht wirklich. mfg |
AW: RGB Farbwerte an einen Mikrocontroller senden
Liste der Anhänge anzeigen (Anzahl: 1)
Ich verwende SYNASER für die serielle Schnittstelle:
SYNASER - Serial Port Synchronous Library for Delphi and Kylix Features of SynaSer This is list of basic features: SynaSer is not components, but only classes and routines. Not needed any installation. Working under Delphi, C++Builder, Kylix or FreePascal. Supported platforms are Win32 and Linux. Support for communicating on serial ports in blocking (synchronous) mode. Supported is high speed of communication. (about few megabytes per second!). Consume very low CPU time. Supported is same communication mechanism as used in Synapse TCP/IP library. Can lock serial port under Linux (like Windows do it). Support for software and hardware handshake. You may open any COM port, if exists in you system (i.e. COM156). You can use Windows or Linux naming of devices on any supported platform! Support for half-duplex RTS driven communication on all supported systems, include linux, WinNT or Win9x! (good for RS485 convertors, etc.) Option for detect device presence before each data transmission. Support for easy use of AT commands for communicate with modems. |
AW: RGB Farbwerte an einen Mikrocontroller senden
Muss ich mir mal anschauen ist wahrscheinlich wieder alles anders ;) hatte mich ja gerade erst mit Comport angefreundet.
Klappt super mit: procedure TForm1.Button2Click(Sender: TObject); var command : AnsiString; begin command := 'L'+Chr(r)+Chr(g)+Chr(b); ComPort1.WriteStr(command); end; Vielen Dank! Werde mich jetzt mal daran machen den Arduino Code neu zu gestalten :D mfg |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz