Archiv verlassen und diese Seite im Standarddesign anzeigen : serielle Schnittstelle mit C unter LInux
Hat schon mal jemand die serielle Schnttstelle unter Linux mit einem kleine C-Programm angesteuert? Oder weiss jemand, wie man das geschickt macht?
Ich würde gerne meine ASURO unter LInux fernsteuern.
Gruss,
stochri
Hallo stochri,
Ich habe mich mal in c++ versucht, es ist ganz einfach die serielle Schnittstelle anzusprechen.
Ich hab da eine Klasse geschrieben, aber in C ist es auch ohne Problemme möglich:
#include "avr.h"
#include <iostream>
using namespace std;
avr::avr(void)
: fd_avr(-1)
{
}
avr::~avr(void)
{
closeDevice();
fd_avr = -1;
}
void avr::waitms(int ms)
{
struct timeval tv;
tv.tv_sec=0;
tv.tv_usec=ms*1000;
select(0, NULL, NULL, NULL, &tv);
}
int avr::open_port(void) {
if (fd_avr != -1) {
//Bereits geöffnet, will nicht nochmal öffen
return 1;
}
struct termios newtio;
fd_avr = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY );
if (fd_avr == -1) {
perror(DEVICE);
return(-1);
}
else {
fcntl(fd_avr, F_SETFL, FNDELAY);
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD ;
newtio.c_iflag = IGNPAR | ICRNL ;
newtio.c_oflag = 0;
newtio.c_lflag &= ~(ICANON);
tcflush(fd_avr, TCIOFLUSH);
tcsetattr(fd_avr,TCSANOW,&newtio);
return fd_avr;
}
}
int avr::write_port(unsigned char _byte){
if (fd_avr == -1) {
cout << "ERROR use avr::open() first" << endl;
return 0;
}
int a = write(fd_avr, &_byte ,1);
return a;
}
int avr::read_port(unsigned char * _byte) {
if (fd_avr == -1) {
cout << "ERROR use avr::open() first" << endl;
return 0;
}
int size = read(fd_avr,_byte,1);
return size ;
}
int avr::getfd()
{
return fd_avr;
}
bool avr::isOpen()
{
return (fd_avr != -1) ? true : false;
}
void avr::closeDevice()
{
if( isOpen() )
close(fd_avr);
fd_avr = -1;
}
Dazu der Header:
#ifndef _AVR_H_
#define _AVR_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <ctype.h>
#include <assert.h>
#define DEVICE "/dev/ttyS0"
#define BAUDRATE B9600
class avr
{
public:
avr(void);
~avr();
void waitms(int);
int open_port(void); // Serielle Schnittstelle öffnen
int write_port(unsigned char); //ein Byte schreiben
int read_port(unsigned char * _byte); //ein Byte lesen
int read_portBlocking(unsigned char * _byte);//Block lesen
int getfd(void); //liefert den Filedescriptor zurück
bool isOpen(void); //Ist der Port schon offen?
void closeDevice(); //Port schliessen
private:
int fd_avr; // Filedescriptor
};
#endif //_AVR_H_
Und ein kleines Testprogramm:
#include "avr.h"
#include <iostream>
using namespace std;
int main (void) {
avr * port = new avr();
unsigned char empfangen;
int a;
port->open_port();
while(1){
port->write_port(255);
port->write_port(1);
port->waitms(500);
port->write_port(254);
port->waitms(5);
port->write_port(1);
port->waitms(500);
port->write_port(255);
port->waitms(5);
port->write_port(0);
port->waitms(500);
port->write_port(254);
port->waitms(5);
port->write_port(0);
port->waitms(500);
port->write_port(253);
port->write_port(0);
port->read_port(&empfangen);
a = empfangen;
port->read_port(&empfangen);
if (empfangen == 0) {
cout << "Temperatur beträgt " << a << " Grad" << endl;
}else {
cout << "Temperatur beträgt " << a << ",5 Grad" << endl;
}
port->waitms(5);
}
return 0;
}
Ich hoffe, Du kommst damit klar.
das Testprogamm macht nichts anderes als als paar Werte an die Serielle zu schicken, womit der Avr seinerseits die Temperaturwerte schickt, die dann am Bildschirm angezeigt werden.
Wenn interesse besteht, suche ich den Link, wo das alles beschreiben ist, jetzt finde ich ihn nicht :-(
Gruß Sebastian
Hallo izaseba,
vielen Dank für die Info. Da hätte ich auch gleich noch eine Frage: Welches Entwicklungssystem verwendest Du? Oder machst Du alles aus der Kommandozeile?
Gruss,
stochri
Ich arbeite sehr gerne in der Konsole, mit Emacs, einem sehr mächtigem Editor, und wenn Du lieber in X arbeiten möchtest und z.B. KDE sowieso drauf hast dann schaue Dir mal den QT Designer an, damit bekommst Du eine schöne Oberfläche, ala Delphi, aber wie gesagt, man braucht da die QT Bibliotheken, die sind ja auch mittlerweile für Windows verfügbar, womit Du plattformunabhängig programmierst.
Gruß Sebastian
Noch ein kleiner Nachtrag,
Auf dieser (http://www.easysw.com/~mike/serial/serial.html#2_5) Seite findest Du alles was Du brauchst.
Ich hoffe, daß Dir das weiterhilft.
Gruß Sebastian
Hallo Izazeba,
im Moment probiere ich es noch auf die "theoretisch" einfache Art und Weise, nämlich mit der Kommandozeile. Aber aus irgendwelchen Gründen geht es nur mit root.
ww@Bigtower:~> echo 1 > /dev/ttyUSB0
bash: /dev/ttyUSB0: Keine Berechtigung
Ich kriege nicht raus, wo ich die Berechtigung für die Schnittstelle freigeben kann ( Suse10.0).
Kannst Du mir helfen?
Gruss,
stochri
Hmmm,
Ich kenne mich mit Suse nicht aus,und weiß nicht, wie gut Deine Linux kenntnise sind, aber machmal ein
ls -l /dev/ttyUSB0
Ich hab noch eine normale serielle Schnittstelle und bei Gentoo sieht es so dann aus:
ls -l /dev/ttyS0
lrwxrwxrwx 1 root root 5 5. Jan 12:25 /dev/ttyS0 -> tts/0
Das heißt soviel, daß /dev/ttyS0 ein symbolischer Link auf /dev/tts/0 ist.
ein
ls -l /dev/tts/0
crw-rw---- 1 root tty 4, 64 5. Jan 12:25 /dev/tts/0
sagt mir dann aus, daß /dev/tts/0 dem root und der Gruppe tty
gehört.
Jetzt mußt Du nur noch feststellen, daß der Zielnutzer, auch Mitglied der Gruppe tty ist, und das geht bei Suse mit Yast oder Yast2, oder wie auch immer.
Aber, wie gesagt, bei Suse muß es nicht unbedingt tty sein, am besten prüfen.
Ich hoffe, daß es Dir weiterhilft.
Gruß Sebastian
Hallo Sebastian,
bei mir kommt dieses
crw-rw---- 1 root uucp 188, 0 2006-01-05 18:27 /dev/ttyUSB0
Ich hatte uccp mit yast schon freigegeben, aber die Berechtigung wurde erst beim Neustart des Computers aktuallisiert, das wusste ich nicht.
Jetzt gehts aber.
Vielen Dank,
stochri
aber die Berechtigung wurde erst beim Neustart des Computers aktuallisiert, das wusste ich nicht.
Nein, es ist kein Windows, sorry habe vegessen zu sagen, daß Du Dich ab, und wieder anmelden sollst :oops:
Die Gruppenzugehörigkeit wird nur beim Anmelden ausgewertet...
Gruß Sebastian
Nein, es ist kein Windows, sorry habe vegessen zu sagen, daß Du Dich ab, und wieder anmelden sollst Embarassed
Jaja, aber eigentlich ist es ja gar nicht so unlogisch.
Ich habe mal einen neuen Thread für die ASURO-Linux-Fersteuerung aufgemacht:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=15726
Aber leider muss ich jedesmal minicom aufmachen, damit die Schnittstelle richtig initialisiert wird. Eigentlich sollte das mit setserial gehen.
Gruss,
stochri
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.