Go Down

Topic: Arduino über Linux Shell Skript steuern / Werte ausgeben (Read 113 times) previous topic - next topic

tchleb

Hi,

ich bin gerade dabei einen Arduino Uno über Linux (seriell) anzusteuern und Werte auszulesen, leider klappt das ganze nicht so ganz. Kann mir wer weiter helfen?
Code: [Select]

#include "U8glib.h"  //https://code.google.com/p/u8glib/
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3   //OWB an PIN 3

 OneWire oneWire(ONE_WIRE_BUS);

 DallasTemperature sensors(&oneWire);

 DeviceAddress sensor1 = { 0x28, 0xFF, 0x19, 0x8B, 0x4C, 0x04, 0x00, 0x3B };
 
 DeviceAddress sensor2 = { 0x28, 0xFF, 0x12, 0x8B, 0x4C, 0x04, 0x00, 0x4B };

   U8GLIB_SSD1306_128X64_2X u8g(U8G_I2C_OPT_NONE);     //Banggood SSD1306 0.96" OLED I2C     http://www.banggood.com/0_96-Inch-White-IIC-I2C-OLED-Display-Module-12864-LED-For-Arduino-p-932606.html
                 //SDA = Pin A4 ; SCL = PIN A5   

  double temp1 = 0;
  double temp2 = 0;
  int led = 13; 

  void u8g_prepare(void)
  {
  //u8g.setFont(u8g_font_6x10);
  //u8g.setFont(u8g_font_fub42n);
  //u8g.setFontRefHeightExtendedText();
  //u8g.setDefaultForegroundColor();
  //u8g.setFontPosTop();
  }

void setup(void)
{
    Serial.begin(9600);
 pinMode(led, OUTPUT);  //PIN 13 (LED) als Ausgang definieren
    sensors.begin();  //DallasTemperature sensoren starten
    u8g.setRot180();     // Display um 180° grehen, wenn erforderlich
  //u8g.setContrast(0x30);
  //u8g_prepare(); 
 }

void draw(void)

    //oben
    u8g.setFont(u8g_font_fub17n);
    u8g.setPrintPos(0, 20);
    u8g.print(temp1);
    u8g.setFont(u8g_font_fub17);
    u8g.drawStr( 75, 20, "C");   

     //unten
    u8g.setFont(u8g_font_fub17n);
    u8g.setPrintPos(0, 50);
    u8g.print(temp2);
    u8g.setFont(u8g_font_fub17);
    u8g.drawStr( 75, 50, "C");
}

void serialcontrol()
{
  int eingabe = 0;
  eingabe = Serial.read();    // seriell einlesen
   //Sensor2 bei eingabe 2 ausgeben
  if (eingabe == '1' )
      {
 Serial.print("Temperatatur Sensor1: ");
 //Serial.println(sensors.getTempCByIndex(sensor1)); 
     Serial.println(temp1); 
      } 

   //Sensor2 bei eingabe 2 ausgeben
  if (eingabe == '2' )
      {
 Serial.print("Temperatatur Sensor2: ");
 //Serial.println(sensors.getTempCByIndex(sensor2)); 
       Serial.println(temp2); 
      } 

    if (eingabe == '3' ) //LED an 13 einschalten
      {
 digitalWrite(led, HIGH);
      }   
  if (eingabe == '4' ) //LED an 13 ausschalten
      {
 digitalWrite(led, LOW);
      } 
}

void loop(void)
{
  sensors.requestTemperatures();
  // temp = sensors.getTempCByIndex(0); //Sensor ohne Adressierung
  temp1 = sensors.getTempC(sensor1);
  temp2 = sensors.getTempC(sensor2);

  // picture loop
  u8g.firstPage();
  do
  { 
    draw();
 serialcontrol();
  }
  while( u8g.nextPage() );

  delay(450); //0.45sekunden
  }



Wenn ich mit -->

Code: [Select]
root@debian:/tmp# echo '2' > /dev/ttyACM0
root@debian:/tmp# echo '1' > /dev/ttyACM0


eine 1 oder 2 an den Arduino schicke bekomme ich die Richtige Ausgabe -->

Code: [Select]
root@debian:/tmp# cat /dev/ttyACM0
Temperatatur Sensor2: 16.62
Temperatatur Sensor1: 16.69



Mit diesen Shell-Skript wollte ich das ganze Automatisieren, nur leider wird das .txt Dokument ohne Inhalt erstellt (Skript lässt sich ausführen und hat 755 Rechte). Wo liegt hier der Fehler?

Code: [Select]
#!/bin/bash

echo '1' > /dev/ttyACM0
cat /dev/ttyACM0 > /tmp/sensor1.txt
sleep60
echo '2' > /dev/ttyACM0
cat /dev/ttyACM0 > /tmp/sensor2.txt
exit


gruss
Tobi

eMeS

Hallo Tobi,

so wie ich das sehe, kommen in Deinem Script das Senden der Anfrage und das Lesen der Antwort zu schnell aufeinander. Außerdem überschreibst die die jeweilige *.txt jedesmal.
Füge zwischen Senden und Empfange ein Sleep ein und ersetzte das Umleitungssymbol '>' durch '>>' (anhängen), dann sollte es klappen (habs aber nicht testen können, nur Theorie ;-)).

Gruß eMeS
Wo ich bin ist nichts - doch überall kann ich nicht sein!

tchleb

Hallo eMeS,

Danke für den Tip  :)
den Fehler mit den Timing habe ich schon gefunden, funktioniert damit leider nicht. Cat weiß mit meiner Syntax nicht wie lange es die Ausgabe in die Datei weiterleiten soll.

Ich habe das ganze mit diesen C Programm teilweise gelöst.

Code: [Select]

./arduino-serial -b 9600 -p /dev/ttyACM0 -d 10000 -r >> sensor.txt


Ein- und Ausgabe lässt sich damit kombinieren, muss ich damit heute weiter testen.

eMeS

Ich mache übrigens was Ähnliches: Ich lese die Werte von der seriellen Schnittstelle ab, aber mit einem Python-Script und schreibe die dann zusammen mit einem Timestamp zur weiteren universellen Verwendung in eine MySQL-Datenbank. Ist universeller als eine Textdatei und läuft sehr stabil. (Auf einem BananaPi)

Gruß eMeS
Wo ich bin ist nichts - doch überall kann ich nicht sein!

tchleb

Genau so etwas suche ich, könntest du bitte dein Python-Script posten?
Ich betreibe eine Seagate Dockstar und eine Seagate Goflex Home (auf beiden Debian)

eMeS

ich such's heute abend mal raus, bin jetzt leider nicht in meinem Bastelparadies ...
Wo ich bin ist nichts - doch überall kann ich nicht sein!


eMeS

Hallo Tobi,

hier mein angekündigtes Python-Script:
Code: [Select]
#!/usr/bin/python
import mysql;
import mysql.connector;
from serial import *
from time import *

try:
    connection = mysql.connector.connect(host = "localhost", user = "xxx", passwd = "yyy", db = "db")
    print 'oK'
except:
    print "Keine Verbindung zum Server"
    exit(0)

ser = Serial('/dev/ttyUSB1', 9600)

while 1 :
    lt = localtime()
    kmp = ser.readline()
    dat = strftime('%Y-%m-%d', lt)
    tim = strftime('%H:%M:%S', lt)
    cursor = connection.cursor()
    cursor.execute("""INSERT INTO tabelle (datum, uhrzeit, pulse_pro_minute) VALUES (%s,%s,%s)""",(dat, tim, kmp))
    cursor.close();
    connection.commit();


Ist eigentlich ganz trivial und wohl auch selbsterklärend.
Im Unterschied zu Dir Frage ich den Arduino nicht an, sondern lese die Daten, die er periodisch (minutentakt) an der seriellen Schnittstelle abliefert.
Solltest Du noch Fragen haben - immer gern.
Gruß eMeS
Wo ich bin ist nichts - doch überall kann ich nicht sein!

Go Up