g++ „Hello World“

g++ „Hello World“

Inhaltsverzeichnis

Unter Linux kann man direkt in einem Texteditor wie Beispielswiese „nano“ das erste C++ Programm erstellen.

Sollte „g++“ noch nicht installiert sein kann man dies mit dem nachfolgendem Befehl erledigen.

sudo apt install g++

Nun erstellt man mit dem Editor „nano“ das erste C++ Programm. Wenn man eine neue Programmiersprache lernt verwendet man eigentlich immer als erstes Programm das „Hello World„.

Hello Wordl C++ (helloworld.cpp)

// 'Hello World!' Programm 
 
#include <iostream>
 
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}


Jetzt nur noch speichern und mit Hilfe des g++ kompilieren.

g++ helloworld.cpp

Der C++  Compiler erzeugt nun ein startfähiges Programm mit dem Namen a.out. Es wird immer die Datei a.out erzeugt wenn kein Programmname angeben wird. 
Starten Sie nun Ihr erstes C++ Programm mit: ./a.out

Geben Sie im Terminal nun nachfolgenden Befehl ein.

g++ helloworld.cpp -o helloworld

Der C++ Compiler erzeugt nun durch den Befehl -o eine startfaehige Datei mit dem Namen Helleworld.

Auch diese Datei wird mit dem Befehl ./Helloworld gestartet.

Ein Arduino sendet PUSH Nachrichten

Wenn man einem Arduino ein Ethernet Shield spendiert ist dieser im Netzwerk ansprechbar. Aber außer ein par Sensoren zu betreiben und LEDs an und aus zu schalten kann er auch PUSH Meldungen senden.



Als erstes benötigt man einen Account bei einem PUSH Dienst. In meinem Beispiel verwende ich den Dienst pushingbox.com.

Weil es den Rahmen hier sprengen würde die vielen Möglichkeiten des Dienstes zu erklären hier ein kleines Video für den „Erstkontakt“.

Nun kann man im Bereich API sich den Sketch für einen Arduino ansehen.

https://www.pushingbox.com/api.php

Hier nun mal der Sketch von pushingbox.com (Stand 2018)

////
//
// General code from http://www.pushingbox.com for Arduino + Ethernet Shield (official) v1.2
//
////

#include <SPI.h>
#include <Ethernet.h>

  /////////////////
 // MODIFY HERE //
/////////////////
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x19 };   // Be sure this address is unique in your network

//Your secret DevID from PushingBox.com. You can use multiple DevID  on multiple Pin if you want
char DEVID1[] = "Your_DevID_Here";        //Scenario : "The mailbox is open"

//Numeric Pin where you connect your switch
uint8_t pinDevid1 = 3; // Example : the mailbox switch is connect to the Pin 3

// Debug mode
boolean DEBUG = true;
  //////////////
 //   End    //
//////////////


char serverName[] = "api.pushingbox.com";
boolean pinDevid1State = false;                // Save the last state of the Pin for DEVID1
boolean lastConnected = false;                 // State of the connection last time through the main loop


// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
  Serial.begin(9600);
  pinMode(pinDevid1, INPUT);
  
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  else{
    Serial.println("Ethernet ready");
    // print the Ethernet board/shield's IP address:
    Serial.print("My IP address: ");
    Serial.println(Ethernet.localIP());
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
}

void loop()
{
      ////
      // Listening for the pinDevid1 state
      ////
      if (digitalRead(pinDevid1) == HIGH && pinDevid1State == false) // switch on pinDevid1 is ON 
      {
        if(DEBUG){Serial.println("pinDevid1 is HIGH");}
        pinDevid1State = true;
        //Sending request to PushingBox when the pin is HIGH
        sendToPushingBox(DEVID1);
      }
       if (digitalRead(pinDevid1) == LOW && pinDevid1State == true) // switch on pinDevid1 is OFF
      {
        if(DEBUG){Serial.println("pinDevid1 is LOW");}
        pinDevid1State = false;
        //Sending request to PushingBox when the pin is LOW
        //sendToPushingBox(DEVID1);    //Here you can run an other scenario by creating a DEVID2 variable
      }
      
      
      //DEBUG part
      // this write the respons from PushingBox Server.
      // You should see a "200 OK"
      if (client.available()) {
        char c = client.read();
        if(DEBUG){Serial.print(c);}
      }
      
      // if there's no net connection, but there was one last time
      // through the loop, then stop the client:
      if (!client.connected() && lastConnected) {
        if(DEBUG){Serial.println();}
        if(DEBUG){Serial.println("disconnecting.");}
        client.stop();
      }
      lastConnected = client.connected();
}


//Function for sending the request to PushingBox
void sendToPushingBox(char devid[]){
  client.stop();
  if(DEBUG){Serial.println("connecting...");}

  if (client.connect(serverName, 80)) {
    if(DEBUG){Serial.println("connected");}

    if(DEBUG){Serial.println("sendind request");}
    client.print("GET /pushingbox?devid=");
    client.print(devid);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(serverName);
    client.println("User-Agent: Arduino");
    client.println();
  } 
  else {
    if(DEBUG){Serial.println("connection failed");}
  }
}

So, nun nur noch deine „Your_DevID_Here“ ändern. Diese kannst du unter „My Service“ neu anlegen.

In meinem Beispiel twittert nun der Arduino bei einem Ereigniss am PIN3.
Natürlich kann man auch einen entsprechenden Dienst aussuchen um eine PUSH Nachricht auf dein Handy zu bekommen.

So einfach ….

DLNA! Oder Videos im ganzen Netzwerk Zuhause

Für alle digitalen Endgeräte die DLNA unterstutzen stellt minidlna den passenden Server zur verfügung. DLNA/UPnP Gerate erkennt der Medienserver automatisch. Der Inhalt des Medienservers kann auf Ihnen als Stream abgerufen werden.

Bevor man allerdings schauen kann muss Installiert werden.

sudo apt-get install minidlna

Als nächster Schritt muss die Konfiguration des minidlna geändert werden. Hierzu muss das File mit einem Editor als root geöffnet werden.

sudo nano /etc/minidlna.conf

Nachfolgende Punkte sind zu ändern:

media_dir=V,/path/to/media
db_dir=/var/lib/minidlna
log_dir=/var/log
log_level=warn
friendly_name=MiniDLNA
inotify=yes
  • media_dir: Das V steht für Video, A fuer Audio und P fuer Bilder gefolgt vom entsprechendem Pfad.
  • db_- und log_dir immer setzen um Fehler leichter zu finden.
  • log_level auf warn lassen. kann recht Hilfreich sein.
  • inotify scannt automatisch Änderungen. Dieser Befehl dient dazu neue Dateien einzupflegen.
  • friendly_name ist der Name des DLNA Servers im Netzwerk.

Nun werden noch die Maximalen Beobachter erhöht. (max_user_watches).

gksudo gedit /etc/sysctl.conf

Wie immer an das Ende springen und folgende Zeile hinzufuegen:

fs.inotify.max_user_watches=1048576

Nun speichern! Mit dem nächsten Befehl werden die Änderungen wirksam gemacht

sudo sysctl -p

Nun noch den Dienst RE-Starten. (reload)

sudo /etc/init.d/minidlna force-reload

Servos mit dem Raspberry ansteuern

Einen Servo an einem Raspberry zu betreiben ist mit der richtigen Bibliothek einfacher als man denkt. Das Stichwort dafuer ist „ServoBlaster“.

ServoBlaster installieren

mkdir -p ~/servoblaster/ 
cd ~/servoblaster/
git clone https://github.com/richardghirst/PiBits
mv PiBits/ServoBlaster/ . && rm -rf PiBits
cd ServoBlaster/user
sudo make install

Mehr ist es nicht. Jetzt noch den Servo mit den GPIO’s des Raspberry verbiden.

  • 5V (Plus)
  • GND (Minus)
  • PIN17 die Datenleitung

Es ist zu empfehlen den Servo direkt an die 5V Stromquelle anzuschliessen. Der Betriebsstrom des Servos kann unter umstaenden Schaeden im Raspberry hervorrufen.

Nachfolgen noch eine Uebersicht welcher P1 Header welchen GPIO anspricht.

 Servo number    GPIO number   Pin in P1 header
          0               4             P1-7
          1              17             P1-11
          2              18             P1-12
          3             21/27           P1-13
          4              22             P1-15
          5              23             P1-16
          6              24             P1-18
          7              25             P1-22

Nun ist es aber an der Zeit fuer den ersten Test in der shell .

echo 1=90 > /dev/servoblaster
sleep 1
echo 1=150 > /dev/servoblaster
sleep 1
echo 1=250 > /dev/servoblaster

Hierbei ist die 1 nach dem echo Befehl der Servo aus der obigen Liste. Also in unserem Beispiel bedeutet es das durch echo 1=90 der Servo an GPIO 17 auf 90 Grad gestellt wird.

Temperatur messen mit dem DS18B20

Besteht mal der Bedarf an einer Temperatur Messung ist der DS18B20 ideal dafuer geeignet. 

DS18B20 Wasserdicht

Gemessen wird mit einem One Wire Bus. Durch diesen Bus ist es moeglich an einem Daten-Pin des Arduino mehrer Messfuehler anzuschliessen. Denn Pins einsparen ist immer von Vorteil.

Beschaltung des DS18B20

Und nun noch der entsprechende Sketch.

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(2);  // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);   

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

Servomotor ansteuern

Development Board

Einen Servo mit einem Arduino anzusteuern ist kein Hexenwerk. Mit nachfolgendem Sketch können zwei unterschiedliche Positionen angefahren werden.

// Servo Libary 
#include <Servo.h>
 
// Neues Objekt
Servo myservo;
int wert_auf;
int wert_zu;
 
void setup()
{
  // Servo an Pin 9 koppeln
  myservo.attach(9);
  Serial.begin(9600);
}
 
void loop()
{
  
   // Servo auf steuern
  wert_auf = 900;
  // 10-bit Wert des Analogeingangs (0-1023) in Winkel 0-180 umrechnen
  wert_auf = map(wert_auf, 0, 1023, 0, 180);  
  myservo.write(wert_auf);
  // Kurze Pause, damit der Servo die neue Position anfahren kann
  delay(1500);

  // Servo zu steuern
  wert_zu = 800;
  // 10-bit Wert des Analogeingangs (0-1023) in Winkel 0-180 umrechnen
  wert_zu = map(wert_zu, 0, 1023, 0, 180);  
  myservo.write(wert_zu);
  // Kurze Pause, damit der Servo die neue Position anfahren kann
   delay(1500);
 

}