Pages: 1 2 [3]   Go Down
Author Topic: Ersatz Fahrrad Computer durch Uno  (Read 5285 times)
0 Members and 1 Guest are viewing this topic.
Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie kann man eigentlich die Anzeige der Kilometer so machen, das die Werte immer an der gleichen Stelle dargestellt werden?

Im Normalfall macht man das, indem man auf eine feste Stellenzahl formatiert.

Beispiel: Der Kilometerzähler soll bis 99999 km auf ganze km ohne Nachkommastellen angezeigt werden, dann formatierst Du den Kilometerstand auf einen String mit 5 Zeichen Breite, keine Nachkommastellen, und wenn Du den String immer an derselben Position ausgibst, erscheinen die Einerstellen immer ganz rechts, die Zehnerstellen als zweite Stelle von rechts usw. und das ganz unabhängig davon, ob der Kilometerstand ein-, zwei-, drei-, vier-, oder fünfstellig ist.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 161
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nun hab ich es auch verstanden. 12345,67 muß dann heißen: 8,2,buffer.

Oder 123,456: 7,3 buffer.

Die Zahl vor dem Komma dient als Platzhalter für zu erwartende Zahlen und die hinter dem Komma für die Nachkommastellen. In Nullstellung wird aber nur die Null vor dem Komma aber alle Nullen nach dem Komma angezeigt.

Ich hoffe das stimmt jetzt so.


Micky
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nun hab ich es auch verstanden. 12345,67 muß dann heißen: 8,2,buffer.

Ja, das sind 8 Zeichen gesamt, 2 Stellen nach dem Dezimalpunkt.

Oder 123,456: 7,3 buffer.

Ja, das sind 7 Zeichen gesamt, 3 Stellen nach dem Dezimalpunkt.

Übrigens: Das Array zur Aufnahme der Zeichen muss immer (Minimum!) um eins länger sein, also 9 bzw 8 für eine Formatierung auf 8 und 7 Stellen: C-Strings werden intern nämlich immer mit einem abschließenden Nullzeichen gespeichert. Wenn der Puffer aus Versehen zu klein ist und Du formatierst über das Pufferende hinaus, können im Programm sehr schwierig zu entdeckende Fehler in anderen Programmstellen auftreten.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 161
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hier mal was zum aktuellen Stand. Ist aber noch nicht ganz fertig. Ein Bild zeigt die Steuereinheit und das andere das Display.


Micky


* K800_SDC11264.JPG (107.67 KB, 800x600 - viewed 45 times.)

* K800_SDC11266.JPG (87.63 KB, 800x600 - viewed 45 times.)
« Last Edit: July 20, 2013, 12:57:16 pm by -Micky » Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 161
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie bekomme ich die große Schrift auf einem 8x2 Display unter? Paßt natürlich so nicht. Und ich weiß nicht wo ich den Code so abändern kann das nur drei Zahlen dargestellt werden.


Micky
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie bekomme ich die große Schrift auf einem 8x2 Display unter? Paßt natürlich so nicht. Und ich weiß nicht wo ich den Code so abändern kann das nur drei Zahlen dargestellt werden.

Das ist jetzt aber die Wärme, oder?

Du brauchst nur die Display-Initialisierung auf das 8x2 Display anpassen und dann mußt Du eben die Ausgabe so kurz halten, dass nicht hinter das achte Zeichen geschrieben wird. Z.B. eine Anzeige nur mit dreistelliger Geschwindigkeit, ohne Nachkommastellen, linksbündig:
Code:
void tachoAnzeige()
{
  byte umdrehungen;
  unsigned long zeit;
  float kph, kilometer;
  int kphRounded;
  char buffer[10];
  noInterrupts();            // Interrupts sperren
    umdrehungen=reedCountSum;// Zählvariable umkopieren
    reedCountSum=0;          // Zählvariable auf 0 zurücksetzen
    zeit=reedMillisSum;      // Zeitzähler umkopieren
    reedMillisSum=0;         // Zeitzähler auf 0 zurücksetzen
  interrupts();              // Interrupts wieder zulassen
  if (umdrehungen>0)
    kph=float(RADUMFANG)*(float)umdrehungen/(float)zeit*3.6;
  else
    kph=0.0; 
  kphRounded=int(kph+0.5); // auf ganze kph gerundet
   
  kphRounded = kphRounded % 1000;       // drop any digits above 999
  printbigchar(kphRounded / 100,0);     // print the speed hundreds
  kphRounded = kphRounded % 100;        // drop any digits above 99
  printbigchar(kphRounded/10,1);        // print the speed tens
  kphRounded = kphRounded % 10;         // drop any digits above 9
  printbigchar(kphRounded,2);           // print the speed ones
}
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 161
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nee, daran liegt es nicht. Ich hab schon alles mögliche versucht. Ich kriege zwar eine zweistellige Anzeige hin, nur brauche ich aber eine dreistellige. Was geholfen hat ist statt long short zu nehmen.

Ich weiß nicht wo man die Nachkommastellen angibt. Bei diesem hier wäre das klar:

 
Code:
lcd.setCursor(0, 0);
  dtostrf(kilometer,9,3,buffer);
  lcd.print(buffer);
  lcd.print(" km");
  lcd.setCursor(0, 1);
  lcd.print("KM/H ");
  dtostrf(kph,5,1,buffer);

nicht aber bei dem von Dir genommenen Code. Hier ist der Code wie ich ihn eben nehme:

Code:
//Anzahl Spalten des Display (8)
//#define LCD_WIDTH 8

//Anzahl Zeilen des Display (2)
//#define LCD_HEIGHT 2

// Pin für Reed-Kontakt, Digital-2 für Interrupt 0
#define REEDPIN 2

// Hardware-Interrupt für den Reed-Pin
#define REEDINTERRUPT 0

// Radumfang in mm
#define RADUMFANG 1540


//#include <LiquidCrystal.h>
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#include <LiquidCrystal_I2C.h> // Für I2C LCD Display
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,8,2);  // I2C LCD Adresse auf 0x20 gesetzt, 16 Zeichen / 2 Zeilen LCD


// build 2-line digit font data array
// Digits are 3 characters wide.
byte bignums[10][2][3] = {
// Define which characters to use for each number. 255 is a solid block; 254 is a space  
// The format is { {TopLeft, TopMiddle, TopRight}, {BottomLeft, BottomMiddle, BottomRight} }
 { {255, 0, 255}, {255, 1, 255} },        // data to display "0"
 { {0, 255, 254}, {1, 255, 1} },          // data to display "1"
 { {2, 2, 255}, {255, 1, 1} },            // data to display "2"
 { {0, 2, 255}, {1, 1, 255} },            // data to display "3"
 { {255, 1, 255}, {254, 254, 255} },      // data to display "4"
 { {255, 2, 2}, {1, 1, 255} },            // data to display "5"
 { {255, 2, 2}, {255, 1, 255} },          // data to display "6"
 { {0, 0, 255}, {254, 255, 254} },        // data to display "7"
 { {255, 2, 255}, {255, 1, 255} },        // data to display "8"
 { {255, 2, 255}, {254, 254, 255} }       // data to display "9"
};

void loadchars() {                        // This subroutine programs the custom character data into the LCD
  lcd.command(64);
// Custom character 0
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  
// Custom character 1
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  
// Custom character 2
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  
// Custom character 3
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  
// Custom character 4
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  
// Custom character 5
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  
// Custom character 6
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  
// Custom character 7
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
 
  lcd.home();
}

void printbigchar(byte digit, byte col) { // This subroutine prints the big font characters on the LCD screen
 if (digit > 9) return;                   // reject anything above 9
 for (int i = 0; i < 2; i++) {            // count i from 0 to 1
   lcd.setCursor(col*4 , i);              // set LCD cursor at correct point
   for (int j = 0; j < 3; j++) {          // count j from 0 to 2
     lcd.write(bignums[digit][i][j]);     // write proper block to LCD from array
   }
   lcd.write(254);                        // write an empty space
 }
 lcd.setCursor(col + 4, 0);               // move the cursor to the top line, col + 4
}


void setup(){
  
  // LCD I2C Initilaisieren und Hintergrundbeleuchtung aktivieren
   lcd.init();
   lcd.backlight();    
  
   lcd.init();                                        // LCD-Anzeige initialisieren
   lcd.clear();
  
  pinMode(REEDPIN, INPUT_PULLUP); // Reedkontakt direkt und ohne Widerstand angeschlossen  
  //lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  loadchars();
  attachInterrupt(REEDINTERRUPT, reedISR, FALLING);
}

volatile byte reedCountSum;
volatile short reedMillisSum;

unsigned short lastReedMillis;

void reedISR()
{
  if (millis()-lastReedMillis>=25)  // 25ms entspricht max. 40 Radumdrehungen pro Sekunde
  {
    reedCountSum++;                 // eine Radumdrehung zählen
    reedMillisSum+=millis()-lastReedMillis;   // Zeit addieren
    lastReedMillis=millis();       // Zeit merken
  }
}

unsigned short gesamtUmdrehungen;

void tachoAnzeige()
{
  byte umdrehungen;
  unsigned short zeit;
  float kph, kilometer;
  int kphRounded;
  char buffer[10];
  noInterrupts();            // Interrupts sperren
    umdrehungen=reedCountSum;// Zählvariable umkopieren
    reedCountSum=0;          // Zählvariable auf 0 zurücksetzen
    zeit=reedMillisSum;      // Zeitzähler umkopieren
    reedMillisSum=0;         // Zeitzähler auf 0 zurücksetzen
  interrupts();              // Interrupts wieder zulassen
  gesamtUmdrehungen+= umdrehungen; // Aufsummieren aller Radumdrehungen
  kilometer=(float)gesamtUmdrehungen*(float)RADUMFANG/1000000.0; // Fahrtkilometerzähler
  if (umdrehungen>0)
    kph=float(RADUMFANG)*(float)umdrehungen/(float)zeit*3.6;
  else
    kph=0.0;  
  /*  
  lcd.setCursor(0, 0);
  dtostrf(kilometer,9,3,buffer);
  lcd.print(buffer);
  lcd.print(" km");
  lcd.setCursor(0, 1);
  lcd.print("KM/H ");
  dtostrf(kph,5,1,buffer);
  */
  kphRounded=int(kph+0.5); // auf ganze kph gerundet
  // Ausgabe kph in grossen Ziffern
  
  kphRounded = kphRounded % 1000;       // drop any digits above 999
  printbigchar(kphRounded / 100,0);     // print the speed hundreds
  kphRounded = kphRounded % 100;        // drop any digits above 99
  printbigchar(kphRounded/10,1);        // print the speed tens
  kphRounded = kphRounded % 10;         // drop any digits above 9
  printbigchar(kphRounded,2);           // print the speed ones
  //lcd.setCursor(12, 1);
  //lcd.print("km/h");
}


unsigned short letzteSekunde=0;
void loop()
{
  unsigned short dieseSekunde=millis()/1000;
  // Tachoanzeige wird genau einmal pro Sekunde aktualisiert
  if (letzteSekunde != dieseSekunde)
  {
    tachoAnzeige();
    letzteSekunde=dieseSekunde;
  }
}

Das entscheidene ist ja wohl der Teil den Du hier vorhin reingesetzt hast. Nur wo bitte muß ich da was ändern?

Hinzu kommt noch das die Anzeige nun viel zu träge reagiert.


Micky

« Last Edit: July 30, 2013, 04:02:51 pm by -Micky » Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nee, daran liegt es nicht. Ich hab schon alles mögliche versucht. Ich kriege zwar eine zweistellige Anzeige hin, nur brauche ich aber eine dreistellige.

Dann nimm wieder das 16x2 Display, ein 8x2 Display ist dafür zu klein!

Für eine Anzeige großer Ziffern mit "printbigchar" brauchst Du immer 3 Zeichen Breite, das macht bei dreistelliger Anzeige:
printbigchar 3 Zeichen + 1 Zeichen Abstand + printbigchar 3 Zeichen + 1 Zeichen Abstand + printbigchar 3 Zeichen
= 11 Zeichen insgesamt
Da ist ein Display mit 8 Zeichen insgesamt zu wenig.

Selbst wenn Du sagst, Geschwindigkeiten unter 200 km/h reichen aus und Du würdest als 1 einen einfachen Strich von 1 Zeichen Breite nehmen, passt es immer noch nicht. Dann brauchst die dargestellte Ziffer "1" per printbigchar zwar 2 Zeichen weniger, macht also 9 statt 11 Zeichen insgesamt, aber 9 ist immer noch eins zuviel für ein Display mit 8 Zeichen in einer Zeile.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 161
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dann liegt es doch nicht daran das ich es nicht hinbekomme. Das Display ist halt ein bißchen zu klein. Das macht aber nichts. Dann nehme ich halt die normale Schriftgröße.

Oder halt eine Vergrößerungsfolie darüber befestigen.


Micky
Logged

Pages: 1 2 [3]   Go Up
Jump to: