-         

Ergebnis 1 bis 10 von 10

Thema: serielle Schnittstelle mit C unter LInux

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.062
    Blog-Einträge
    2

    serielle Schnittstelle mit C unter LInux

    Anzeige

    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

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    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:

    Code:
    #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:

    Code:
    #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:

    Code:
    #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

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.062
    Blog-Einträge
    2
    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

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    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

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    Noch ein kleiner Nachtrag,

    Auf dieser Seite findest Du alles was Du brauchst.
    Ich hoffe, daß Dir das weiterhilft.

    Gruß Sebastian

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.062
    Blog-Einträge
    2
    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

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    Hmmm,
    Ich kenne mich mit Suse nicht aus,und weiß nicht, wie gut Deine Linux kenntnise sind, aber machmal ein
    Code:
    ls -l /dev/ttyUSB0
    Ich hab noch eine normale serielle Schnittstelle und bei Gentoo sieht es so dann aus:

    Code:
    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
    Code:
    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

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.062
    Blog-Einträge
    2
    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

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    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

    Die Gruppenzugehörigkeit wird nur beim Anmelden ausgewertet...

    Gruß Sebastian

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    12.06.2005
    Ort
    Südwestdeutschland
    Beiträge
    1.062
    Blog-Einträge
    2
    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:
    http://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

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •