-         

Ergebnis 1 bis 8 von 8

Thema: [gelöst] best. wert "aufteilen"

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544

    [gelöst] best. wert "aufteilen"

    Anzeige

    servus,

    ich möchte mir jetzt ein analoges "messgerät" mit einem atmega32 bauen.
    dieses soll (vorerst) einfach eine spannung zwischen 0 und 5 volt an einem best. analogen port (porta) des atmega einlesen und dann auf/mit zwei 7-segment anzeigen widergeben.
    soweit der plan, doch:

    die anzeige soll eine kommastelle haben (z.b. 2,5 volt).
    deswegen muss ich den wert,der eingelesen wird (nach dem umwandeln in die volt zahl ....... aus 200 werrden z.b. ungefähr 0,9 volt) aufteilen.
    hier, in diesem beispiel (0,9 volt) muss ich auf der ersten anzeige eine 0 darstellen, auf der zweiten anzeige eine 9.
    wie teile ich einen wert zwischen 0 und 5 mit einer nachkommastelle auf zwei variablen auf (softwaremässig)????

    mfg
    chris

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    11.08.2005
    Beiträge
    178
    hallo,

    also da du eine kommastelle willst würde ich mit 10-fachem adc messwert rechnen, denn dann kann mit integer arithmetik gerechnet werden, was sich positiv auf die maschinencodegrösse und performance auswirkt. weiters bieten sich bei den divisionen durch 2er potenzen bitshifts an (1024 = 2^10). und do solltest mindestens auf eine weitere kommastelle runden.

    um deine eigendliche frage zu beantworten:
    angenommen du freundest dich mit dem vorschlag des 10-fachen adc wertes an... dann erhältst du die ziffer vor dem komma durch dividision mit 10, und die nachkomma ziffer mit einem modulo 10.

    so würde mein vorschlag als c code aussehen: (nicht getestet, es ist schon spät und bier!)
    Code:
    #define AREF_VOLTAGE 50 // 10x the voltage for integer arithmetics
    ...
    uint_16 dividend = AREF_VOLTAGE * adc_value; // we need this twice
    uint_8 voltage = dividend >> 10; // division by 1024 (=2^10)
    uint_16 remainder = dividend - (voltage << 10); //for rounding
    if(remainder >= 512) voltage++; // minimal rounding without math lib
    //if(remainder >> 9) voltage++; // could be more efficient...
    uint_8 ones = voltage / 10; //note: integer division
    uint_8 tenths = voltage % 10; // modulo
    vermutlich liesse sich der code weiter optimieren... vieleicht hat ja noch jemand eine idee


    lg + hth
    "A robot with guns for arms shooting a plane made out of guns that fires guns" - Nelson Muntz

  3. #3
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Wenn es sicher ist, daß du immer nur eine Vorkommastelle hast:
    Code:
    DIM einer AS BYTE
    DIM komma AS BYTE
    DIM zehntel AS BYTE
    DIM strg AS string * 6 AT einer OVERLAY
    
    DIM volt as SINGLE    ' das ist die Voltzahl, also z.B.  0.9
    
    strg = str(volt)   ' macht aus 0.9 --den string "0.9"
    
    davon steht "0" wegen OVERLAY immer auch in der Variablen "einer"  
    der dezimalpunkt in "komma" 
    "9" steht in "zehntel"
    den rest kannst du
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    danke für eure antworten!!

    @johns
    leider kann ich deinem code überhauptnichts entnehmen, da ich c gar nicht verstehe *schaem*
    trotzdem danke dür deine antwort

    @PicNick
    ich habe deinen code so einigermassen verstanden und habe jetzt noch die wichtigsten sachen angehängt:

    $regfile = "m32def.dat"
    $crystal = 16000000

    Config Adc = Single , Prescaler = Auto
    Config Portb = Output
    Config Portc = Output

    Portc.0 = 1
    Portc.1 = 1
    Portc.2 = 1
    Portc.3 = 1
    Portc.4 = 1
    Portc.5 = 1
    Portc.6 = 1
    Portc.7 = 1

    DIM einer AS BYTE
    DIM komma AS BYTE
    DIM zehntel AS BYTE
    Dim Strg As String * 6 At Einer Overlay
    Dim X As Word
    Dim Volt As Single
    Dim A As Integer

    A = 5 * X
    Volt = A / 1024

    Strg = Str(volt)

    Do
    Start Adc
    X = Getadc(0)
    If Einer = 1 Then
    Portc.0 = 0
    Elseif Einer = 2 Then
    Portc.0 = 1
    Portc.1 = 0
    Elseif Einer = 3 Then
    Portc.1 = 1
    Portc.2 = 0
    End If
    Loop

    End


    allerdings leuchtet keine led auf dem RN-Control dabei auf!! was habe ich falsch gemacht/vergessen??

    mfg
    chris

  5. #5
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Code:
    $regfile = "m32def.dat"
    $crystal = 16000000
    
    Config Adc = Single , Prescaler = Auto
    Config Portb = Output
    Config Portc = Output
    
    Portc.0 = 1
    Portc.1 = 1
    Portc.2 = 1
    Portc.3 = 1
    Portc.4 = 1
    Portc.5 = 1
    Portc.6 = 1
    Portc.7 = 1
    
    DIM einer AS BYTE
    DIM komma AS BYTE
    DIM zehntel AS BYTE
    Dim Strg As String * 6 At Einer Overlay
    Dim X As Word
    Dim Volt As Single
    
    $const faktor  = 5 / 1024  ' feste werte soll gleich der kompiler ausrechnen
    
           Start Adc
    
    Do
           X = Getadc(0)
          Volt = X                        ' umwandeln in gleitkomma
          Volt = Volt * faktor               
     
          Strg = Str(volt)  
          einer = einer AND &H0F    '  aus ascii wird  &H00-&H05
    
          select case einer
          case 0:        'pin setzen für 0
          case 1:        'pin setzen für 1
          case 2:        'pin setzen für 2
          case 3:        'pin setzen für 3
          case 4:        'pin setzen für 4
          case else:    'pin setzen für was weiss der Teufel
          end select
    Loop
    End
    Bei deinen Segment-Pins blick' ich jetzt nicht durch, aber das ist ja nicht das Problem
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    danke, das funtioniert jetzt ganz gut !!

    aber ich möchte ja auch noch zehntel darstellen, wie kann ich das den machen????

    tut mir leid, dass ich das nicht selbst kann, aber ich kann noch nicht sehr lange programmieren und brauche deßhalb ein paar starthilfen.

    mfg
    chris

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Nun, genauso, nur sind es mehr "case"
    Code:
          zehntel = zehntel AND &H0F    '  aus ascii wird  &H00-&H09
    
          select case einer 
          case 0:        'pin setzen für 0 
          case 1:        'pin setzen für 1 
          case 2:        'pin setzen für 2 
          case 3:        'pin setzen für 3 
    ........
          case 9:        'pin setzen für 9
          case else:    'pin setzen für was weiss der Teufel 
          end select 
    Loop
    da gibt es statt "case" was besseres, aber ich bin grad im Druck und kann dir das jetzt nicht aufschreiben
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    24
    Beiträge
    1.544
    ok,danke.
    jetzt funzts!!

    mfg
    chris

Berechtigungen

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