Posts mit dem Label Analog werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Analog werden angezeigt. Alle Posts anzeigen

Sonntag, 18. März 2018

Analog Anzeige auf dem TFT 1.8" zeichnen


Eine Analog Anzeige ist schon etwas Nostalgisch und haben eigentlich wegen ihrer ungenauen Ablesbarkeit keinen nutzen mehr. Aber das sollte kein Hindernis sein, dennoch solche Analogen Display auf einem Arduino zu Zeichnen. Das man dazu nicht viel machen muss, zeige ich in diesen Post mit einem Code Schnipsel.
  • Arduino UNO / Duemilanove
  • TFT Display 128x160
  • Ggf. TFT Display Shield

Die Bibliothek für TFT hat fast alle Methoden, um das Zeichnen einer Analogen Anzeige zu ermöglich. Damit man nicht zu sehr in Grafik Experimente verfällt, ist es hilfreich sich vorher eine Skizze zu machen. Mit den Rechtecken und Kreisen und einer richtigen Reihenfolge, kann die Grundlage der Analoganzeige gezeichnet werden. Jedoch der Interessante Teil ist, das Animieren der Anzeigenadel.

Anzeigenadel
Der Aufbau der Anzeigenadel ist sehr überschaubar und kommt mit einfacher Schulmathematik aus. Für das Beispiel wird allerdings nur eine Linie gezeichnet. Eine Pfeilspitze würde beim Zeichnen mehr Zeit aufwenden und eine flüssige Darstellung wäre ggf. nicht möglich. Zumindest nicht mit der Bibliothek, da das Pixelzeichnen nicht in ein Backbuffer des TFT geschrieben werden kann.
Später beim Zeichnen eines Wertzustandes, muss der vorige Stand zurück gesetzt werden. Hierbei reicht es die Anzeigenadel mit dem vorigen Wert nochmal mit der Hintergrundfarbe zu Zeichnen.

Code Schnipsel
Der folgende Programmcode Zeichnet nur die Anzeigenadel. Als Eingabewert wird der Pin A0 mit 'analogRead' ausgelesen. Die vollständige Analoganzeige findet ihr wieder auf meinem Github Repository.

 #include <SPI.h>  
 #include <TFT.h>  
 #include <Wire.h>  
 #define CS  10  
 #define DC  9  
 #define RST 8  
 TFT mScreen = TFT(CS, DC, RST);  
 float mValuePointer = 0.0;            
 float mValuePointerLast = 0.0;         
 void setup() {  
  Wire.begin();  
  mScreen.begin();  
  mScreen.background(0, 0, 0);  
  pinMode(A0, INPUT);   
 }  
 void loop() {  
  mValuePointer = ((float)analogRead(A0) / 1023.0) * 100.0;  
  mScreen.stroke(0, 0, 0);  
  renderValuePointer(40, 40, 25, mValuePointerLast);  
  mScreen.stroke(35, 200, 140);  
  renderValuePointer(40, 40, 25, mValuePointer);  
  mValuePointerLast = mValuePointer;  
  delay(10);  
 }  
 void renderValuePointer(int locationX, int locationY, float diffRadius, float val) {  
  float section = 2.0 * 3.14 / 100.0;  
  float sectionStart = section * 5;  
  float center = diffRadius / 2.0;  
  val = val + 50.0;  
  float x = diffRadius * cos(section * val) + diffRadius;  
  float y = diffRadius * sin(section * val) + diffRadius;  
  mScreen.line(locationX + diffRadius, locationY + diffRadius, locationX + x , locationY + y );  
 }  

Wenn ihr das auf eure Umgebung hoch lädt, dann sollte eine Line auf dem Bildschirm zu sehen sein. Das Zappeln ist praktisch gesehen ein Rauschen, wenn kein Pull-Up oder Pull-Down Widerstand gesetzt wurde auf Pin A0.


Kurzes
Wie ihr seht, steckt da nicht viel dahinter und schon schafft man etwas mehr Optik.



Freitag, 16. Januar 2015

Arduino Control (Teil 4) – Potentiometer Wert am PC ausgeben

image

Der Arduino kann auch analoge Signale einlesen. Dieser Wert kann zwischen 0 und 1023 liegen. Für dieses Beispiel wird ein Potentiometer verwendet, der möglichst hochohmig sein sollte. In meinem Fall habe ich einen 470 Ohm Stellwiederstand verwendet. Empfohlen ist 1k Ohm.

image

Der Quellcode ähnelt dem Beispiel für den Button. Nur müssen hier für den Empfang zwei Bytes zu einem Wert zusammengesetzt werden. Das Stichwort ist hier Byte Shifting. Das erste Byte wird um acht Bits nach links verschoben, um die Bits von 9 bis 16 abzubilden. Das zweite Byte bleibt für die ersten acht Bits.

static void Main(string[] args)
{
   // Die Verwendete COM Verbindung
    // sollte der aus dem Arduino Programm entsprechen.
    SerialPort sp = new SerialPort("COM16", 115200);

    // Event zuweisen für den Empfang.
    sp.DataReceived += sp_DataReceived;

   // Verbindung öffnen.
    // Wenn das Programm gestartet ist,
    // sollte der Arduino bereits mit dem PC verbunden sein.
    sp.Open();

    while (true)
    {
       // Nur warten.
        Thread.Sleep(1000);
    }
}


// Wird ausgeführt, wenn Daten im Empfangspuffer vorhanden sind.
static void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // SerialPort aus 'sender' casten.
    SerialPort sp = (SerialPort)sender;

    // Bytes einlesen vom Empfang und auf die Console wiedergeben.
    byte[] buffer = new byte[2];
    if (sp.Read(buffer, 0, 2) != 0)
    {
        Console.Clear();
        // Die zwei empfangenen Byte müssen wieder zusammengelegt werden,
        // um den Eigentlichen Wert wiederzugeben.
        Console.WriteLine("Received: {0}", (int)buffer[0] << 8 | buffer[1]);
    }
}

Der Input verwendet diesmal analogRead(), statt des digitalRead(). Unterscheidet sich der Wert zu dem zuletzt versendeten, dann soll der neue gemessene Wert gesendet werden. Der Wert kann bis zu 1023 betragen und passt nicht in ein Byte. Daher wird dieser in zwei Bytes aufgeteilt und anschließend versendet. Am Ende wird eine Verzögerung von 100 Millisekunden festgelegt, um zwischen den Sendungen eine Lücke zu erzeugen. Ansonsten kann nicht erkannt werden, welches das erste und das zweite Byte ist.

// Pin Nummer A0 vom Arduino
int pinPegel = A0;

// Enthält den letzten Button Zustand.
int lastValue = 0;

void setup()
{
  // Baudrate wie bei dem C# Programm
  Serial.begin(115200);
  pinMode(pinPegel, INPUT);
}

void loop()
{
  // Status am Pin abfragen
  int readValue = analogRead(pinPegel);
 
  // Nur Inhalt im If ausführen,
  // wenn der Status sich geändert hat.
  if(readValue != lastValue)
  {
   // Member Field überschreiben.
    lastValue = readValue;
  
   // Buffer vorbereiten und
   // den Wert in zwei bytes aufteilen.
    byte ba[2];
    ba[0] = (byte)((readValue >> 8) & 0xff);
    ba[1] = (byte)(readValue & 0xff);
   
    // Buffer Inhalt von zwei Bytes senden.
    Serial.write(ba, 2);
       
    // Ermöglicht das Erkennen vom 1. und 2. Byte
    // in dem zwischen den Sendungen eine Pause gesetzt wird.

    delay(100);
  }
}

Damit ist auch schon alles getan.

 

Quellcode zum Download

Gehäuseentwurf für Signalleuchten (ESP32)

RGB LEDs und LIPO Akkus sind bestellt. Weil ich bereits die Abmessungen habe, kann ich schon mal mit dem Gehäuseentwurf in Blender anfangen....