Hi Chris,
das hört sich doch schonmal nicht verkehrt an genauso wollte ich das eigentlich auch haben, da ich die Licher gerne mit einem OpenWRT Gerät steuern wollte. Entweder ne WRT54G oder ne Fonera da bin ich mir noch nicht sicher aber den WRT hab ich eh noch über von daher wirds darauf hinauslaufen. Wäre natürlich nicht schlecht wenn die Steuerung auch an einem PC funktionieren würde.
Könntest du mir deinen Code mal zukommen lassen ich würd mir die Änderungen ganz gerne mal anschauen.
Ich hab gestern mal getestet mein Fnordlicht mit meinem USB->UART Adapter zu verbinden. Tendenziell hat sich was getan nur nicht das was ich wollte. Aber ich werde da glaub nochmal mit dem Adapter rumspielen müssen.
Grüße
Frederik
Am 7. Mai 2009 20:22 schrieb Pohl temp2006@pohlcity.de:
Frederik Krämer schrieb:
So ich hab mich mal ein wenig eingelesen und gestern auch die Paderborner Firmware ausgetestet, die blinkt bei meinem Licht allerdings nur wild rum.
Der RS485 nutzt ja den UART des Fnordlichts und da ich eine externe Steuerung der Lichter angestrebt habe muss ich mir da noch was überlegen. Aber ich werde wohl auf den RS485 setzen. Gibts da irgendwo mehr Informationen drüber als das was in RS485-PROTOCOL steht?
Vor allem wie ich die Dinger dann adressiere ist mir momentan noch ein kleines Rätsel
Hi Frederik,
also was ich rausgelesen habe aus dem aktuellen Code:
- Ansteuerung nur über etherape, da 9-bit über seriell/RS485
- Ansonsten steht die Adresse im Makefile (RS348_ADDRESS)
- Befehle siehe fnordlicht.c (sind ordentlich kommentiert)
ich habe meine Hardware soweit, dass die ganze RS485 Sache läuft, das fnordlicht macht auch was Softwareanpassungen:
- 8 bit (mehr geht mit einem PC nicht), nur 19200 baud - da muss
allerdings am Protokoll gedreht werden, da urspünglich das 1. Bit für die erkennung Adresse/Befehl war 2. naja bin noch am basteln, aber das Licht reagiert immerhin, auch wenn momentan noch im "debug"-modus, da ich das Protokoll noch anpassen muss 3. Einweg-Steuerung, d.h. die Hardware ist so gebaut, dass auf fnorlichtseite nur empfangen werden kann.
Wenn Du willst, stell ich mal meinen Kram zusammen und schick in Dir.
Viele Grüße,
Chris
Frederik Krämer schrieb:
Könntest du mir deinen Code mal zukommen lassen ich würd mir die Änderungen ganz gerne mal anschauen.
Kommt demnächst.
Ich hab mir mal ein "Protokoll" am Wochenende überlegt, um das 9te bit zu lösen. Das will ich noch ausprobieren: (Außerdem bin ich grade nicht in Reichweite des Bastelrechners, der zudem aus ist)
Folgende Protokoll-idee: Es werden immer 5 Byte übertragen 1. Byte: 6bit Adresse, 2bit Kommando 2. -5. Byte Daten
Adresse 63 ist broadcast (RS458 erlaubt ohne Repeater sowieso nur 32)
Kommando wie gehabt: 1: reset (daten egal) 2: set color (3byte daten: rgb) 3: fade to color (4byte daten: time rgb)
Warum immer 5 Byte? ist einfacher, als Aufgrund des Kommandos zu entscheiden, wieviel Daten kommen. Nullterminiert geht auch nicht, da ja durchaus auch eine 0 für eine Farbe eingestellt werden kann, sind eben binärdaten und nicht ascii.
Naja, mal schaun, ob es funktioniert.
Ich melde mich und hänge das nächste mal die Daten mit an.
Viele Grüße,
Chris
Joa das hört sich gut an.
hab heute nochmal ein Licht für mich und eins für nen Kumpel aufgebaut. Hab diesmal mal LEDs mit 120° Abstrahwinkel genommen. Auf jeden Fall sehr geil damit. nur da die roten soweit in der Mitte sind sieht man wenn rot leuchtet je nach Einbau einen Schatten, habs eben mal provisorisch in eine Ikea Fado gepackt. Denke da wirds auch final eingebaut.
Grüße
Frederik
Am 10. Mai 2009 20:01 schrieb Pohl temp2006@pohlcity.de:
Frederik Krämer schrieb:
Könntest du mir deinen Code mal zukommen lassen ich würd mir die Änderungen ganz gerne mal anschauen.
Kommt demnächst.
Ich hab mir mal ein "Protokoll" am Wochenende überlegt, um das 9te bit zu lösen. Das will ich noch ausprobieren: (Außerdem bin ich grade nicht in Reichweite des Bastelrechners, der zudem aus ist)
Folgende Protokoll-idee: Es werden immer 5 Byte übertragen
- Byte: 6bit Adresse, 2bit Kommando
- -5. Byte Daten
Adresse 63 ist broadcast (RS458 erlaubt ohne Repeater sowieso nur 32)
Kommando wie gehabt: 1: reset (daten egal) 2: set color (3byte daten: rgb) 3: fade to color (4byte daten: time rgb)
Warum immer 5 Byte? ist einfacher, als Aufgrund des Kommandos zu entscheiden, wieviel Daten kommen. Nullterminiert geht auch nicht, da ja durchaus auch eine 0 für eine Farbe eingestellt werden kann, sind eben binärdaten und nicht ascii.
Naja, mal schaun, ob es funktioniert.
Ich melde mich und hänge das nächste mal die Daten mit an.
Viele Grüße,
Chris
Hallo Frederik und alle anderen
so ich bin die Sache mal andersrum angegangen und die Fnordlich Firmware nur bzgl. Baudrate angepasst auf 19200 bd * bei der RS485 Initialierung anstelle 8 (115200bd) den Wert 51 eingetragen. * im Makefile die RS485-Adresse vergeben * in config.h nur rs485 aktivieren
Vorab: es funktioniert. Das Licht reagiert so wie es soll! :-D (auch wenn ich das timing beim fade (noch) nicht ganz kapiert habe)
Problem wie bekomme ich den PC dazu, das zu senden, was ich will. D.H. * 1 Start Bit * 8 Datenbits * 1 bit addr/data (das 9te Bit für den MPCM) * 1 Stopp bit da ist mir doch die Parity eingefallen, die genau an der richtigen Stelle sitzt.
Die UARTS im PC ermöglichen es die parity "static" zu setzen, leider nur bei direktem ansprechen über die Register (ähm, geht das überhaupt noch so direkt an 0x2f8 was zu senden?), die stty/termios devices können das nicht. Wie dann? Ich setze den Parity Mode eben entsprechend der zu sendenden Daten so, dass das Bit passt, also * Adresse 9tes bit=1 * Daten 9tes bit=0.
Resultat ist das unten angehängte Programm.
Ach ja, die Hardware:
* am PC: http://www.amateurfunkbasteln.de/rs485/rs485.html * am fnordlicht: von obiger Schaltung nur den LTC 485 nehmen RX und TX mit den entsprechenden Leitungen am fnordlicht verbinden, Pin 2 und 3 auf masse, dann ist der auf Dauerempfang. (Strom nehm' ich mir auch vom fnordlicht) * geht auch ohne Bus: direkt nur mit dem "lochraster"-Pegelwandler
So, das wars. Wenn ich jetzt noch eine Erklärung zum fading bekommen würde...
Kommentare erwünscht
Chris
---------------- Das Programm ----------------
/* fnordRS485 Version: 0.1 Author: Christian Pohl Date: 2009-05-12 */
#include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <stdlib.h>
int openPort(char *port) { int fh; /* filehandle */ struct termios options; fh = open(port, O_RDWR | O_NOCTTY | O_NDELAY); if (fh == -1) { perror("openPort: Unable to open port"); return (0); } else{ fcntl(fh, F_SETFL, 0); /* read current options */ tcgetattr(fh, &options); /* in/out 19200bd */ cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); /* 8bit */ options.c_cflag &= ~CSIZE; /* Mask the character size bits */ options.c_cflag |= CS8; /* Select 8 data bits */ /* rts/cts to enable rs485 transmitter with rts */ options.c_cflag |= CRTSCTS; /* one stop bit */ options.c_cflag &= ~CSTOPB; /* enable parity */ options.c_cflag |= PARENB; /* set new options */ tcsetattr(fh, TCSANOW, &options); return (fh); } }
/* return 0 if even number of 1, return 1 if odd number of 1 */ unsigned isOdd(unsigned char x) { x = x ^ (x >> 4); x = x ^ (x >> 2); x = x ^ (x >> 1);
return ((unsigned)(x & 1)); }
/* sendByte byte requires 9th bit (parity) to be parityBit addrcmd: 9th bit must be 1 data: 9th bit must be 0 returns number of sent bytes (1 on succes, 0 on error) */ int sendByte(int fh, unsigned char byte, unsigned int parityBit) { struct termios options; tcgetattr(fh, &options);
/* precompute parity and set paritymode so that the paritybit will be parityBit */ if(isOdd(byte) != parityBit) { options.c_cflag |= PARODD; printf( "8o1\n"); } else { options.c_cflag &= ~PARODD; printf ("8e1\n"); } tcsetattr(fh, TCSADRAIN, &options); return write(fh,&byte,1); }
/* argv: 1 addr 2 cmd 3 data 1 4 data 2 5 data 3 6 ... */ int main(int argc, char *argv[]) {
int fh; int i; unsigned char addr;
if(argc<=2) { printf("Usage:\n"); printf("%s address command [data1] [data2] ... \n",argv[0]); printf("Address: 0-255 (0 is broadcast)\n"); printf("Command: 1 (softreset), 2 (set color, 3 databytes), 3 (fade color, 5 databytes)\n"); printf("All databytes: 0-255\n"); printf("No checks at all! Let's see what happens if you provide wrong data :-D\n"); exit(1); }
fh=openPort("/dev/ttyS0"); if(fh == 0) { exit(2); }
addr = atoi(argv[1]); printf("Sending to address %d\n",atoi(argv[1])); if(sendByte(fh,addr,1)<=0) { perror("error write addrcmd"); exit(3); } for(i=2;i<argc;i++) { printf("Sending data: [%d]: %d\n",i-1,atoi(argv[i])); if(sendByte(fh,atoi(argv[i]),0)<=0) { perror("error write data"); exit(4); } }
close(fh); exit(0); }
Hallo,
das sieht doch schonmal gut aus. Ich werd das ganze demnächst mal ausprobieren, weiß allerdings nicht ob ichs diese Woche noch schaffe.
Da ich auch die RS485 Bauteile momentan nicht hab werd ich wohl erstmal mit meinem USB -> UART Adapter versuchen das ganze ans laufen zu bringen.
Aber wie das mit dem Fading funktionieren soll hab ich leider auch noch nicht rausgefunden, das habe ich nämlich auch schon versucht aus dem Code herauszulesen. Aber eventuell wird das ja noch was.
Grüße
Frederik
Am 12. Mai 2009 22:18 schrieb Pohl temp2006@pohlcity.de:
Hallo Frederik und alle anderen
so ich bin die Sache mal andersrum angegangen und die Fnordlich Firmware nur bzgl. Baudrate angepasst auf 19200 bd
- bei der RS485 Initialierung anstelle 8 (115200bd) den Wert 51
eingetragen.
- im Makefile die RS485-Adresse vergeben
- in config.h nur rs485 aktivieren
Vorab: es funktioniert. Das Licht reagiert so wie es soll! :-D (auch wenn ich das timing beim fade (noch) nicht ganz kapiert habe)
Problem wie bekomme ich den PC dazu, das zu senden, was ich will. D.H.
- 1 Start Bit
- 8 Datenbits
- 1 bit addr/data (das 9te Bit für den MPCM)
- 1 Stopp bit
da ist mir doch die Parity eingefallen, die genau an der richtigen Stelle sitzt.
Die UARTS im PC ermöglichen es die parity "static" zu setzen, leider nur bei direktem ansprechen über die Register (ähm, geht das überhaupt noch so direkt an 0x2f8 was zu senden?), die stty/termios devices können das nicht. Wie dann? Ich setze den Parity Mode eben entsprechend der zu sendenden Daten so, dass das Bit passt, also
- Adresse 9tes bit=1
- Daten 9tes bit=0.
Resultat ist das unten angehängte Programm.
Ach ja, die Hardware:
- am PC: http://www.amateurfunkbasteln.de/rs485/rs485.html
- am fnordlicht: von obiger Schaltung nur den LTC 485 nehmen RX und TX mit
den entsprechenden Leitungen am fnordlicht verbinden, Pin 2 und 3 auf masse, dann ist der auf Dauerempfang. (Strom nehm' ich mir auch vom fnordlicht)
- geht auch ohne Bus: direkt nur mit dem "lochraster"-Pegelwandler
So, das wars. Wenn ich jetzt noch eine Erklärung zum fading bekommen würde...
Kommentare erwünscht
Chris
Das Programm
/* fnordRS485 Version: 0.1 Author: Christian Pohl Date: 2009-05-12 */
#include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <stdlib.h>
int openPort(char *port) { int fh; /* filehandle */ struct termios options; fh = open(port, O_RDWR | O_NOCTTY | O_NDELAY); if (fh == -1) { perror("openPort: Unable to open port"); return (0); } else{ fcntl(fh, F_SETFL, 0); /* read current options */ tcgetattr(fh, &options); /* in/out 19200bd */ cfsetispeed(&options, B19200); cfsetospeed(&options, B19200); /* Enable the receiver and set local mode */ options.c_cflag |= (CLOCAL | CREAD); /* 8bit */ options.c_cflag &= ~CSIZE; /* Mask the character size bits */ options.c_cflag |= CS8; /* Select 8 data bits */ /* rts/cts to enable rs485 transmitter with rts */ options.c_cflag |= CRTSCTS; /* one stop bit */ options.c_cflag &= ~CSTOPB; /* enable parity */ options.c_cflag |= PARENB; /* set new options */ tcsetattr(fh, TCSANOW, &options); return (fh); } }
/* return 0 if even number of 1, return 1 if odd number of 1 */ unsigned isOdd(unsigned char x) { x = x ^ (x >> 4); x = x ^ (x >> 2); x = x ^ (x >> 1);
return ((unsigned)(x & 1));
}
/* sendByte byte requires 9th bit (parity) to be parityBit addrcmd: 9th bit must be 1 data: 9th bit must be 0 returns number of sent bytes (1 on succes, 0 on error) */ int sendByte(int fh, unsigned char byte, unsigned int parityBit) { struct termios options; tcgetattr(fh, &options);
/* precompute parity and set paritymode so that the paritybit will be
parityBit */ if(isOdd(byte) != parityBit) { options.c_cflag |= PARODD; printf( "8o1\n"); } else { options.c_cflag &= ~PARODD; printf ("8e1\n"); } tcsetattr(fh, TCSADRAIN, &options); return write(fh,&byte,1); }
/* argv: 1 addr 2 cmd 3 data 1 4 data 2 5 data 3 6 ... */ int main(int argc, char *argv[]) {
int fh; int i; unsigned char addr; if(argc<=2) { printf("Usage:\n"); printf("%s address command [data1] [data2] ... \n",argv[0]); printf("Address: 0-255 (0 is broadcast)\n"); printf("Command: 1 (softreset), 2 (set color, 3 databytes), 3
(fade color, 5 databytes)\n"); printf("All databytes: 0-255\n"); printf("No checks at all! Let's see what happens if you provide wrong data :-D\n"); exit(1); }
fh=openPort("/dev/ttyS0"); if(fh == 0) { exit(2); } addr = atoi(argv[1]); printf("Sending to address %d\n",atoi(argv[1])); if(sendByte(fh,addr,1)<=0) { perror("error write addrcmd"); exit(3); } for(i=2;i<argc;i++) { printf("Sending data: [%d]: %d\n",i-1,atoi(argv[i])); if(sendByte(fh,atoi(argv[i]),0)<=0) { perror("error write data"); exit(4); } } close(fh); exit(0);
}