-         
Ergebnis 1 bis 8 von 8

Thema: Falsche Variablen, oder was ist verkehrt? (secret voltmeter)

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied Avatar von basteluwe
    Registriert seit
    15.11.2012
    Beiträge
    102

    Falsche Variablen, oder was ist verkehrt? (secret voltmeter)

    Anzeige

    Hallo Leute,
    ich möchte in mein kleines Arduino Pro Mini-Si4703-Radio eine Batterieüberwachung integrieren.
    Auf dieser Seite habe ich die Anregung gefunden und mein Test-Code sieht nun so aus:
    Code:
    float volt;
    char akku[4];
    
    long readVcc() {
      long result;
      // Read 1.1V reference against AVcc
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Convert
      while (bit_is_set(ADCSRA,ADSC));
      result = ADCL;
      result |= ADCH<<8;
      result = 1126400L / result; // Back-calculate AVcc in mV
      return result;
    }
    void setup() {
      Serial.begin(9600);
    }
    
    void loop()
    {
      volt = (readVcc()/1000);
      dtostrf(volts, 2, 1, akku);
      Serial.print( readVcc(), DEC );
      Serial.print("\t");
      Serial.println(volt,2);
      delay(1000);
    }
    Dies ist das für mich unbefriedigende Ergebnis:

    Klicke auf die Grafik für eine größere Ansicht

Name:	com.JPG
Hits:	11
Größe:	30,9 KB
ID:	33170
    Der Wert für readVcc stimmt. Die Variable "volt" ist als float definiert. Warum bekomme ich dann bei der Division (readVcc/1000) keine Nachkommawerte angezeigt?

    Ratlose Grüße,
    Uwe

    - - - Aktualisiert - - -

    Uuups,
    die Zeile: "dtostrf(volts, 2, 1, akku);" gehört da natürlich nicht rein, ändert aber nichts am Problem.
    Sorry!

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.986
    Zitat Zitat von basteluwe Beitrag anzeigen
    Hallo Leute,
    ich möchte in mein kleines Arduino Pro Mini-Si4703-Radio eine Batterieüberwachung integrieren.
    Auf dieser Seite habe ich die Anregung gefunden und mein Test-Code sieht nun so aus:
    Code:
    float volt;
    char akku[4];
    
    long readVcc() {
      long result;
      // Read 1.1V reference against AVcc
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Convert
      while (bit_is_set(ADCSRA,ADSC));
      result = ADCL;
      result |= ADCH<<8;
      result = 1126400L / result; // Back-calculate AVcc in mV
      return result;
    }
    void setup() {
      Serial.begin(9600);
    }
    
    void loop()
    {
      volt = (readVcc()/1000);
      dtostrf(volts, 2, 1, akku);
      Serial.print( readVcc(), DEC );
      Serial.print("\t");
      Serial.println(volt,2);
      delay(1000);
    }
    Dies ist das für mich unbefriedigende Ergebnis:

    Klicke auf die Grafik für eine größere Ansicht

Name:	com.JPG
Hits:	11
Größe:	30,9 KB
ID:	33170
    Der Wert für readVcc stimmt. Die Variable "volt" ist als float definiert. Warum bekomme ich dann bei der Division (readVcc/1000) keine Nachkommawerte angezeigt?

    Ratlose Grüße,
    Uwe

    - - - Aktualisiert - - -

    Uuups,
    die Zeile: "dtostrf(volts, 2, 1, akku);" gehört da natürlich nicht rein, ändert aber nichts am Problem.
    Sorry!
    long readVcc()

    returned eine Integer Zahl (long = int32_t) , die dann durch 1000 dividiert wird - das gibt dann ebenfalls Integer
    wenn du durch 1000.0 dividierst, gibt es float

    du kannst auch explizit type-casten:
    volt = (float)readVcc()/(float)1000;
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied Avatar von basteluwe
    Registriert seit
    15.11.2012
    Beiträge
    102
    Wow!
    SO schnell und SO richtig!!! Danke!
    Ich hatte angenommen, wenn ich eine "float" definiere und dann das Ergebnis der Division da rein lege, würde es von allein Gleitkomma werden.
    Falsch gedacht und wieder was gelernt.
    Ich hab es schon in mein Radio-script eingebaut und nun sieht die Anzeige auch aus, wie sie soll:
    Klicke auf die Grafik für eine größere Ansicht

Name:	display.jpg
Hits:	16
Größe:	58,0 KB
ID:	33171

    Nochmals Dank!
    Uwe

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.986
    super, gerne!
    Aus eigenem Interesse:
    Könntest du mal deine Hardware und deinen Code hier einstellen? Finde ich mega interessant!
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied Avatar von basteluwe
    Registriert seit
    15.11.2012
    Beiträge
    102
    Gerne, kein Problem!
    Die Hardware setzt sich zusammen aus:
    • Arduino Pro Mini
    • Breakout Board Si4703
    • OLED 0.96" 128x64
    • Micro USB Lipo-Lader TP4056 (1000mA)
    • 3,7V 2000 mA LiPo Akku
    • 5x Mikrotaster
    • NF-Verstärker TDA7233 (mit Beschaltung)
    • Lautsprecher 4Ohm

    Hier ist ein Bild vom Versuchsaufbau:
    Klicke auf die Grafik für eine größere Ansicht

Name:	board02.jpg
Hits:	13
Größe:	120,5 KB
ID:	33177

    Auf dem Aufbau sitzt leider im Moment statt des TDA7233, auf den ich noch warte, ein LM386. Der 386 geht für meine Zwecke leider nicht, weil seine Betriebsspannung zu hoch ist. das ist auch der Grund, warum zwar Arduino/SI4703/OLED schon aus dem LiPo betrieben werden, der LM386 aber 7V vom Testboard bekommt.

    Hier mein Code:
    Code:
    /**************************************************************************
     * This code is a modification/extract of several example-codes that come *
     * with various si4703-libraries. Libraries used here are fetched from:   *
     *         http://www.mathertel.de/Arduino/RadioLibrary.aspx              *
     * Not sure if other libraries work with same code.                       *
     * 5 pushbuttons control the FM-radio (see comments in code)              *
     * OLED-display shows 3 lines:                                            *
     *  1- "frequency"                                                        *
     *  2- "station name" or "scan mode"                                      *
     *  3- "volume level" + "battery voltage" or "CHARGE BATTERY"             *
     * Code for voltage monitoring is fetched from:                           *
     * https://code.google.com/archive/p/tinkerit/wikis/SecretVoltmeter.wiki  *
     *                                                                        *
     * U.Galepp Jan./2018                                                     *
     **************************************************************************/
    
    #include <Arduino.h>
    #include <Wire.h>
    #include <radio.h>
    #include <si4703.h>
    #include "U8glib.h"
    
    U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);  // define type of display (OLED 0.96" 128x64 pix)
    
    #define FIX_BAND     RADIO_BAND_FM            // the band that will be tuned by this sketch is FM.
    #define FIX_STATION  8760                     // station at start-up is 87.60 MHz
    #define FIX_VOLUME   7                        // volume level at start-up
    
    SI4703 radio;                                 // Create an instance of Class for Si4703 Chip
    
    int volume = FIX_VOLUME;
    int button_1 = 3;                             // button volume up an Pin 3
    int button_2 = 4;                             // button volume down an Pin 4
    int button_3 = 5;                             // button station swap an Pin 5
    int button_4 = 6;                             // button scan up an Pin 6
    int button_5 = 7;                             // button scan down an Pin 7
    int buttonState_1 = 0;
    int buttonState_2 = 0;
    int buttonState_3 = 0;
    int buttonState_4 = 0;
    int buttonState_5 = 0;
    int flag = 0;                               // used for decission to show "Station Name" or "scan mode"
    int stationNr = 0;
    int fmFreq[10] = {8760, 8820, 9100, 9350, 9500, 10030, 10080, 10280, 10330, 10480};
    char* fmName[10] = {"   NDR 1 MV", "   NDR Kultur", "   NDR 1 MV", "   NDR 2 MV", 
                       "     N-JOY", "Deutschlandfunk", "  Antenne MV", "   NDR Info", 
                        "Radio Paradiso", "  Ostseewelle"};
    char vol[2];
    float volts;
    char akku[4];
    
    long readVcc() {
      long result;
                                                // Read 1.1V reference against AVcc
      ADMUX = _BV(REFS0) | _BV(MUX3) 
                  | _BV(MUX2) | _BV(MUX1);
      delay(2);                                 // Wait for Vref to settle
      ADCSRA |= _BV(ADSC);                      // Convert
      while (bit_is_set(ADCSRA,ADSC));
      result = ADCL;
      result |= ADCH<<8;
      result = 1126400L / result;               // Back-calculate AVcc in mV
      return result;
    }
    
    /******************************
     *           Setup            *
     *****************************/
    void setup() {
    
      radio.init();                               // initialize radio 
      
      radio.setBandFrequency(FIX_BAND, FIX_STATION);
      radio.setMono(false);
      radio.setMute(false);
    
      pinMode(button_1, INPUT);                   // define button Pins
      pinMode(button_2, INPUT);                   // -||-
      pinMode(button_3, INPUT);                   // -||-
      pinMode(button_4, INPUT);                   // -||-
      pinMode(button_5, INPUT);                   // -||-
      digitalWrite(button_1, HIGH);               // button-Pin Pull-up
      digitalWrite(button_2, HIGH);               // -||-
      digitalWrite(button_3, HIGH);               // -||-
      digitalWrite(button_4, HIGH);               // -||-
      digitalWrite(button_5, HIGH);               // -||-
    } 
    
    /******************************
     * Subroutine Display on OLED *
     *****************************/
    void displayData()                           
      {
      volts = (float)readVcc()/(float)1000;
        
      char s[12];
      radio.formatFrequency(s, sizeof(s));        // format frequency value to output like: "87,60 MHz"
    
        u8g.firstPage(); 
        do {
        u8g.drawFrame(0,0,128,64);                // display frame around screen
        u8g.setFont(u8g_font_timB14);
        u8g.drawStr(15, 22, s);
        u8g.setFont(u8g_font_unifont);
        if(flag==0)
          {
          u8g.drawStr(4, 44, fmName[stationNr]);  // if fequency from array, take name from array too
          }
        if(flag==1)
         {
          u8g.drawStr(25, 44, "scan mode");       // if frequency from scan, show "scan mode"
         }
    
        if(volts > 3.3)                           // if VCC > 3.3V display "Volume" & "Volt"       
            {
            u8g.setFont(u8g_font_6x13);
            u8g.drawStr(6, 59,"Volume: ");                          
            sprintf (vol, "%d", volume);          // change int "volume" to char "vol"                 
            u8g.drawStr(50, 59, vol);
            u8g.drawStr(68, 59,"Bat:");
            dtostrf(volts, 2, 1, akku);           // change float "volts" to char "akku"  
            u8g.drawStr(94, 59,akku);
            u8g.drawStr(115, 59,"V");
            }
           else                                   // if VCC >= 3.3V display "CHARGE BATTERY"
           {
            u8g.drawStr(6, 59,"CHARGE BATTERY");
           }
          } 
         while( u8g.nextPage() );
      }
    
    /******************************
     *         Main Loop          *
     *****************************/
    void loop() 
      {
      buttonState_1 = digitalRead(button_1);
      buttonState_2 = digitalRead(button_2);
      buttonState_3 = digitalRead(button_3);
      buttonState_4 = digitalRead(button_4);
      buttonState_5 = digitalRead(button_5);
      
      if (buttonState_1 == LOW) 
        {
          volume ++;
          if (volume == 16) volume = 15;
          radio.setVolume(volume);
          delay(100);
         } 
         
      if (buttonState_2 == LOW) 
        {
          volume --;
          if (volume < 0) volume = 0;
          radio.setVolume(volume);
          delay(100);
          } 
          
      if (buttonState_3 == LOW)
        {
          stationNr ++;
          if (stationNr == 10) stationNr = 0;
          radio.setFrequency(fmFreq[stationNr]);
          flag = 0;
          delay(500);
          }
          
      if (buttonState_4 == LOW)
        {
          radio.seekUp();
          flag = 1;
          delay(200);
          }
    
      if (buttonState_5 == LOW)
        {
          radio.seekDown();
          flag = 1;
          delay(200);
          }   
      displayData();
     }
    Falls Profis den Kopf schütteln, seid gnädig. Ich bin nur interessierter Laie, was das Programmieren angeht. Für Hinweise auf echte Fehler oder sinnvolle Verbesserungen bin ich aber sehr dankbar. Zumindest läuft der Code in der Form erst mal.
    Das Ding soll dann in eine hölzerne Angelbox eingebaut werden. Falls das auch interessiert, gibt es hier auf meiner Webseite Details zu sehen.

    Gruß Uwe

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.986
    super gut!
    denkst du, es wäre möglich, dass man auch einen Sendersuchlauf programmiert?
    Mit i-Tüpfelchen: Sender-Namen-Anzeige per RDS/TLC ?
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied Avatar von basteluwe
    Registriert seit
    15.11.2012
    Beiträge
    102
    Einen Sendersuchlauf gibt es im Sinne von scan-Up / scan-Down. Das geht allerdings nur bis zur nächsten Station, die der Chip findet. Es funktioniert mehr oder weniger gut. Leider stoppt es nicht immer auf Abstimmungsmaximum. Das Ergebnis liegt oft etwas neben dem Peak. Diese Scan-Funktion hat mein Code schon (Button 4+5). Ich denke das ist was, wenn ich nicht in der Home-Zone bin. Für Zuhause gibt's ja die vorprogrammierten Stationen.
    RDS kann der Chip auch! Hab ich seriell getestet, aber dann in meinem Code erst noch weggelassen. Die Example scripts der Library brachten bei mir für RDS nur bei 2 von 10 empfangbaren Stationen Ergebnisse. Ich fand, da macht die RDS-Auswertung keinen großen Sinn.

    Gruß Uwe

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.986
    danke für die Info - klingt aber trotzdem richtig interessant!
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

Ähnliche Themen

  1. Software Voltmeter
    Von Janiiix3 im Forum Software, Algorithmen und KI
    Antworten: 11
    Letzter Beitrag: 30.11.2010, 18:02
  2. [ERLEDIGT] Verkehrt ausgerichtetes Pitotrohr ? (beantwortet)
    Von PICture im Forum Mechanik
    Antworten: 13
    Letzter Beitrag: 07.11.2009, 13:37
  3. Ampere und Voltmeter mit AVR
    Von Natrium im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 25.10.2008, 10:26
  4. Variablen in XRAM oder ERAM (ATTiny13) ???
    Von HPM im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 31.12.2007, 13:27
  5. Hat schon jemand mal einen Sharp IR Sensor verkehrt gepolt?
    Von Einstein im Forum Sensoren / Sensorik
    Antworten: 5
    Letzter Beitrag: 23.12.2003, 21:07

Berechtigungen

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