C Neuling hat ein paar fragen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hi all,

    bin nun im ersten semester ET/IT und da wir dort C durchnehmen hab ich mir gedacht kannste das gleich verbinden und ein bischen auf dem PI experimentieren.

    gesagt getan habe allerdings noch ein paar fragen aber erstmal zum hintergrund.

    Ich habe mir reedkontakte von ebay geordert um fenster und türen zu überwachen.

    nun habe ich erstmal nur die zimmertür mit einem kontakt versehen.
    wenn der kontakt geschlossen ist liegt an gpio 22 (pin 15) 3.3V an also logisch 1.

    Das programm zur abfrage hab ich von dieser [http://raspberrypiguide.de/howtos/raspberry-pi-gpio-how-to/]Seite[/url] und auf meine bedürfnisse ein klein wenig angepasst.

    - Wenn nun die Tür geöffnet wird wird eine Led auf steckbrett angeschaltet und geht wieder aus wenn die Tür zu ist.
    Nun ist es ja so, das die while bedingung 1 ist was heist die while schleife ist endloss....ich weiss leider nicht wieviel so eine endlosschleife an ressourcen zieht ich denke mir aber es müsste doch bestimmt einen eleganteren weg geben eine statusänderung eines gpios oder eines anderen wertes ab zu fragen oder? Es wird so wies jetzt ist ja immer printf bei jedem schleifendurchlauf rein geschrieben möchte dies jedoch nur bei änderung des GPIO zustandes immer nur einmal in der konsole als ausgabe haben wie mach ich das?


    -was ich auch gerne machen würde wäre anstatt der leuchtenden Led, Datum und uhrzeit in eine text datei schreiben zu lassen. leider weis ich nicht wie ich dies bewergstelliegen könnte?
    die zeitfunktion habe ich bereits. jedoch meckert visual studio rum das die funktion veraltet wären error C4996 habe das zwar mit #pragma warning (disable :4996) ausführbar für visual studio gemacht jedoch weis ich nicht ob ich das nun auch im script im raspberry übernehmen muss.

    soo viele fragen so viel text, schonmal vielen dank fürs lesen und eure Zeit.

    mfg tree

    Edit :Seitenlink wurde gefixt!

    Einmal editiert, zuletzt von treeshort (5. Dezember 2014 um 08:30)

  • Servus,


    ...
    nun habe ich erstmal nur die zimmertür mit einem kontakt versehen.
    ...

    da bietet es sich zunächst mal an, eine Skizze / Schaltplan zu posten. Relativ einfach und sehr anschaulich sind z.B. Steckbrett-Ansichten, die mit Fritzing erstellt wurden. Eagle wäre auch eine Alternative, die ebenfalls kostenlos zum Download bereitsteht.
    Ich gehe zudem davon aus, dass Du Dich bereits eingehend mit den Grundlagen des RPi beschäftigt hast, was GPIOs, Ströme, Spannungen und Eigenschaften betrifft.
    Falls nicht, wäre es imho eine sehr gute Idee, das schnellsten nachzuholen.


    ...
    ... von dieser Seite und ...
    ...


    Der Link zeigt auf eine Datei auf Deinem PC ... ;)


    ...
    ... die while bedingung 1 ist was heist die while schleife ist endloss....ich weiss leider nicht wieviel so eine endlosschleife an ressourcen zieht
    ...


    die wird in ihrem timeslice 100% der CPU verballern ...



    ...
    ... eleganteren weg geben eine statusänderung eines gpios oder eines anderen wertes ab zu fragen oder? Es wird so wies jetzt ist ja immer printf bei jedem schleifendurchlauf rein geschrieben möchte dies jedoch nur bei änderung des GPIO zustandes immer nur einmal in der konsole als ausgabe haben wie mach ich das?
    ...


    da gibt es mehrere Lösungsansätze.
    Möglich wäre, dass Du Dir den Staus merkst, und nur dann eine Aktion ausführst, wenn er sich geändert hat:


    zudem wird pro Durchlauf eine Wartezeit von 100 ms eingebaut. Dadurch entlastest Du die CPU ganz erheblich.
    Lösung Nr. 2 wäre aus meiner Sicht allerdings erheblich besser.
    Die Lib bietet die Möglichkeit, eine ISR für einen bestimmten Zustandswechsel eines GPIO-Pins festzulegen:

    Code
    int wiringPiISR (int pin, int edgeType,  void (*function)(void)) ;


    Es lohnt sich in diesem Zusammenhang, mal die Funktionen dieser Lib zu studieren. Die Beschreibung für die Interrupt-Service-Routine findest Du z.B. -> hier <-.


    ...
    ... die zeitfunktion habe ich bereits. jedoch meckert visual studio rum das die funktion veraltet wären error C4996 habe das zwar mit #pragma warning (disable :4996) ausführbar für visual studio gemacht jedoch weis ich nicht ob ich das nun auch im script im raspberry übernehmen muss.


    vergiss Visual Studio mit seinem Windows-spezifischen Schnick-Schnack ... Du befindest Dich auf einem Linux-System und da bin ich der festen Überzeugung, hat der Krempel aus Redmond nichts drauf verloren. Die Wegelagerer der Gates-Company habe m.E. erfolgreich ihr Windows versaut - das s muß ihnen reichen ...
    Ist jetzt allerdings meine persönliche Meinung zu Gates & Co.

    Such Dir ne nette IDE für Linux ( Code::Blocks finde ich z.B. genial, Geany wird auch oft und gern genommen ) und schreib die Sourcen auf dem Raspi - ohne überflüssige CR/NL Kombinationen. Vermeide zudem die Unsitte von Umlauten aus der Windows-Welt und Du wirst keine Probleme bekommen.

    Vielleicht noch zur Vervollständigung: in manchen Fällen kann es sinnvoll sein, statt der wiringPi eine andere Library zu verwenden.
    Die, die mir jetzt ad hoc einfallen wären die pigpio, die ich bevorzuge und die bcm2835, die afaik bei Entwicklern auch sehr verbreitet ist.
    Es lohnt sich auf alle Fälle, die beiden mal unter die Lupe zu nehmen, welchen Umfang und welche Features sie mitbringen. So kann z.B. der socket-Server der pigpio manchmal ganz hilfreich sein und eine Menge Arbeit ersparen.

    //EDIT: war wohl eher ein Fehlclick, Deinen Beitrag auf erledigt zu setzen, oder?

    cu und viel Erfolg,
    -ds-

  • Visual Studio ist eine top gratis IDE. 'Windows-spezifischen Schnick-Schnack', 'Krempel aus Redmond', 'Windows versaut' sicher nicht. Ist meine persönlich Meinung .
    Habe jarelang für Linux und Windows damit programmiert.

    Aber danke für den Tip Code::Blocks ,werde ich mir mal ansehen. Obwohl ich das ja für 'X-Windows-spezifischen Schnick-Schnack' halte der auf einem Liunx System nichts zu suchen hat. ;)


    Zu bedenken:
    http://www.airspayce.com/mikem/bcm2835/ steht unter der GPL und kann somit nur für quelloffene Projekte verwendet werden.

    pigpio ist wohl CC0

    WiringPi ist LGPL

    Einmal editiert, zuletzt von evil (5. Dezember 2014 um 08:45)

  • Also ich bin mit windows aufgewachsen und gewohnheiten lassen sich bekantlich schwehr ändern :) und visual studio benutze ich halt im studium und benutze es daher recht häufig.

    Um auf deine fragen ein zu gehen:

    ja ich bin mit der elektronik der gpios vertraut. Hardware mäßig funktioniert auch alles.
    habe einen externen pullup wiederstand für den eingang und türkontakt benutzt wäre vielleicht noch
    gut zu wissen wie man die internen wiederstände auf up oder down softwareseitig setzen kann.

    fritzing ist mir bekannt für einen einfachen schalter und ne led wollte ich es jedoch nicht unbedingt bemühen sollte eigentlich klar sein wie ichs beschrieben habe.

    das mit dem merker erinnert mich an SPS schaltung aus meiner ausbildung nach sowas hab ich quasi gesucht ^^
    ich werde mich morgen mal drann setzen und deine tipps ausprobieren schonmal vielen dank für die hilfe ich halte dich auf dem laufenden.

    PS: das schreiben von datum und uhrzeit in eine .txt hast du leider noch nicht behandelt, würdest du das noch machen ? wäre sehr cool!

    Einmal editiert, zuletzt von treeshort (5. Dezember 2014 um 08:54)

  • Hi,


    ...
    Ist meine persönlich Meinung .
    ...


    so hat jeder seine Präferenzen :) ...


    ...
    Aber danke für den Tip Code::Blocks ,werde ich mir mal ansehen. Obwohl ich das ja für 'X-Windows-spezifischen Schnick-Schnack' halte der auf einem Liunx System nichts zu suchen hat. ;)
    ...


    Code::Blocks ist es eine nette, allgemein gehaltene IDE, die dank X11 und ssh -X auch remote bedient werden kann. Mach bei umfangreicheren Projekten imho durchaus Sinn ... vor allem, weil vi und Makefiles nicht jedermanns Sache sind.


    ...
    Zu bedenken:
    http://www.airspayce.com/mikem/bcm2835/ steht unter der GPL und kann somit nur für quelloffene Projekte verwendet werden.
    pigpio ist wohl CC0
    WiringPi ist LGPL


    Ich denke, dass beim Einsatz im Privatbereich oder zur Lernzwecken die Lizenz eher zweitrangig sein dürfte. Und quelloffen ist sowieso gut. Schliesslich verwendet man ja auch das Wissen anderer in seinem Programm und erwartet das noch dazu kostenlos, fehlerfrei und gut dokumentiert. Also ist es nur fair, auch wieder was zurückzugeben.


    ...
    PS: das schreiben von datum und uhrzeit in eine .txt hast du leider noch nicht behandelt, würdest du das noch machen ? wäre sehr cool!


    Datum und Uhrzeit würde ich in Form eines UNIX-Timestamps ablegen. Dieser Wert ist die Anzahl der seit dem 1.1.1970 00:00 Uhr vergangenen Sekunden.
    Das hat den Vorteil, dass Du mit diesem Wert einfach rechnen kannst wie mit jedem anderen Zahlenwert und die Umwandlung in ein lesbares Datum dem System überlassen kannst.
    Um z.B. den Zeitpunkt in 6 Tage und 4 Stunden zu berechnen, brauchst Du auf den time()-Wert nur ((6*24*60*60)+(4*60*60)) hinzuaddieren. Diesen Wert kannst Du dann einfach mit z.B. localtime() in das entsprechende Datum konvertieren lassen.

    cu,
    -ds-

  • sorry das ich mich erst Monate später wieder melde aber hatte Privat viel um die Ohren und bin noch garnicht weiter gekommen... würde gerne eine delay funktion einfügen allerdings sagt mir linux so wie windows das er delay(1000) nicht kennt....habt ihr da ma nen link zu?

    EDIT: Hab die delay funktion nun selbst herraus gefunden und mit ihr ist die CPU last von 100% auf 5% gesunken. So weit so gut.

    Nun würde ich gerne die Zeit bei jedem öffnen und schließen loggen und in einer Textdatei als Logfile hinterlegen. Hat jemand da vielleicht ein Beispiel parat?

    Einmal editiert, zuletzt von treeshort (8. Mai 2015 um 03:43)

  • Hallo Treeshort,

    ich möchte Dir nicht zu nahe treten, aber was hältst Du davon, Dich in ein gutes C-Tutorial zu vergraben?

    Deine Fragen deuten darauf hin, dass Du das bisher noch nicht gemacht hast. Du bringst Dich um das Gefühl, beim Programmieren selber etwas hinbekommen zu haben.

    Wenn Du so suchst, dann wirst Du auch Tutorials finden, die Dich dort abholen, dass Du auch etwas verstehst. Denn die Ausführungen, die Du bisher erhalten hast, scheinen bei Dir nicht angekommen zu sein - sonst würde Deine Rückmeldung anders aussehen.

    Beste Grüße!

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (8. Mai 2015 um 07:58)

  • Sorry Andreas ich bin nicht der Meinung das ich dutzende Stunden im web rumsurfen muss um mir alles einzelnd zusammen zu suchen wenn es doch ein Forum mit kompetenten und hilfsbereiten Usern gibt( in deinem fall trifft wenn wohl nur ersteres zu).

    Da Mir allerdings keiner weiter helfen wollte, musste ich nun doch viele Stunden opfern.

    Nun habe ich den Code soweit zusammen und es funktioniert auch berits ganz gut auf dem Raspberry.

    Ich hätte jetzt nur noch eine kleine Frage.

    Bei fopen(dateiname.txt, "a");

    würde ich gerne als Dateiname noch zum Namen das Datum hinzufügen allerdings stellt sich der Kompiler bei jedem Versuch quer. :@

    Jemand eine Idee wie man das aktuelle Datum in den Dateiennamen einfügen kann?


    Anbei der soweit fertige Code fals ihn jemand benutzen möchte.

    compiliert werden muss das ganze mit dem Befehl:

    g++ dateiname.cpp -o dateiname -lwiringPi

    PS: Ich weis man hätte noch mit funktionen usw das ganze Porgramm etwas kleiner schreiben können. Es funktioniert so aber auch ganz passabel.

    Einmal editiert, zuletzt von treeshort (8. Mai 2015 um 23:48)

  • Moin,


    ...
    Jemand eine Idee wie man das aktuelle Datum in den Dateiennamen einfügen kann?
    ...

    ja, so zum Beispiel:


    was passiert da?
    Es wird ein char-Array reserviert, das die maximal zulässige Länge eines Dateinamens hat.
    Über die -> time() <- resp. -> localtime() <- Funktion werden das aktuelle Datum und die aktuelle Uhrzeit ermittelt.
    Der sprintf() baut das ganze dann zu einem String zusammen.
    Wenn Du andere/weitere Daten benötigst, einfach mal in die verlinkten man-pages schauen.

    cu,
    -ds-

  • Hey vielem dank für die Hilfe!

    habe jetzt auch alles soweit angepasst und compilieren funktioniert auch.
    Aber leider sagt er mir nun wenn ich das script ausführe das er
    die Datei nicht geoffnet bekommt.
    Hoffe du weist worans liegt, könnte mir vorstellen das es an dem Logfilename in der fopen funktion scheitert.

    Ausgabe:

    Tuer ist geschlossen!
    Datei konnte nicht geoeffnet werden.

    pi@raspberry: .....

  • Au dem hier

    Code
    char string1[] = "Tuer wurde geoeffnet!!!\n";
    char string2[] = "Tuer wurde geschlossen!!!\n";
    char string3[] = "Programmstart! Tuer ist geoeffnet!\n";
    char string4[] = "Programmstart! Tuer ist geschlossen!\n";

    würde ich Folgendes machen:

    Code
    const char *sStrings[4];
    
    
    sStrings[0] = "Tuer wurde geoeffnet!!!\n";
    sStrings[1] = "Tuer wurde geschlossen!!!\n";
    sStrings[2] = "Programmstart! Tuer ist geoeffnet!\n";
    sStrings[3] = "Programmstart! Tuer ist geschlossen!\n";
  • Hallöle,


    ...
    Datei konnte nicht geoeffnet werden.

    pi@raspberry: .....

    hm ... gib doch mal den erzeugten Dateinamen mit

    Code
    fprintf(stderr, "%s\n", Logfilename);
    oder 
    printf("%s\n", Logfilename);

    uns schau mal, ob Du die Datei per Hand anlegen kannst ...

    cu,
    -ds-

  • Vielleicht ist die Datei ja noch in irgendeinem anderen Programm exklusiv geöffnet ?

  • Also habe jetzt die Datei mal als root ausgeführt erstmal ohne deine änderung.

    Nun sagt er

    root@raspberrypi:/etc/default/Doorsensor# ./newdoor
    Tuer ist geschlossen!
    Datei konnte nicht geoeffnet werden.
    Speicherzugriffsfehler

    wenn ich deine änderungen direkt in die if ((pHeute.... nach der sprintf einfüge, kommt die ausgabe so:

    root@raspberrypi:/etc/default/Doorsensor# ./newdoor


    Tuer ist geschlossen!
    Datei konnte nicht geoeffnet werden.
    Speicherzugriffsfehler

    von deinen ausgabe befehlen gibt er also nur das \n aus.
    (habe beide befehle nacheinander eingefügt)

    Einmal editiert, zuletzt von treeshort (10. Mai 2015 um 22:37)

  • So ... jetzt aber ...

    bau doch das Programm mal nach folgender Vorlage um. Ist nicht viel ... zuerst mal in die main()-Funktion ...


    ...
    int main()
    {
    FILE *fp;

    char Logfilename[PATH_MAX];
    struct tm *pHeute;


    die folgenden zwei Zeilen einfügen.

    Code
    time_t timeVar;
            timeVar = time(NULL);


    und dann noch die if-Abfrage ändern in:

    Code
    if((pHeute = localtime(&timeVar)) != NULL)


    Das war's auch schon ... kommt davon, wenn ich den Code ohne zu testen nur so mal schnell runterschreibe ;)
    Jetzt sollte es funktionieren.

    cheers,
    -ds-

  • OffTopic:

    noch ein kleiner Tipp, da du ja ET/IT machst:
    gewöhne dir direkt eine vernünftige Code-Formatierung an und nutze etwas mehr Arrays.
    Außerdem nutze bessere, logischer Namen für Variablen.

  • Ok super jetzt funktioniert alles wie es soll! :thumbs1:

    Hier Pack ich ma das Funktionierende Script rein falls noch jemand es verwenden möchte muss er dann nicht den ganzen Faden durchlesen ;)

    Kleine Verständnisfrage wozu dient dieses tim(NULL) speziel das Null in der Klammer?
    time_t timeVar; ....wird hier der sekundenwert von 1970 bis heute in der Variablen timeVar gespeichert? Warum hier kein = ?
    Sorry für die Anfängerfragen^^ alles andere erschließt sich mir emhr oder weniger ;)


    micha Rpi

    Hey in wiefern sollte ich die denn Formatieren?
    Eingerückt habe ich die Zeilen doch? Müsstest du schonmal konkreter werden wenn du was Kritisierst ^^.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!