MAX7219 zusammen mit Dot Matrix und 7 Segment benutzen.

Guten Abend,

ich habe mal wieder eine Frage. Ich spiele zur Zeit DIRT 2. Ist ein Ralley Spiel. Zu dem Spiel gibt es noch ein Programm welches X-Sim heißt. Dieses Programm kann über die serielle Schnittstelle Daten wie Drehzahl, Geschwindigkeit und Gang ausgeben.

Ich habe ein Beispiel Sketch, welches die Daten über ein LCD Display ausgibt. Das funktioniert auch soweit.

Jetzt möchte ich zudem LCD auch noch ein DOT Matrix für die Ganganzeige und die 7 Segment für Drehzahl und Geschwindigkeit benutzen.

Die Bauteile habe ich schon alle dafür. Die DOT Matrix und 7 Segment habe ich einzeln schon zum laufen bekommen. Aber mit verschiedenen Librarys.

Folgende Fragen:

Wie kann ich beide anzeigen zusammen benutzen?
DOUT vom Matrix ist mit DIN 7 Segment verbunden.

Hier der Link zum Sketchauthor.
http://www.x-sim.de/forum/viewtopic.php?f=40&t=1083

Und hier der Code, mit dem das LCD funktioniert. Ich habe bei mir nur die LCD Library geändert auf I2C.

//  X-Sim Sample code for receiving OBD2 values from the extractor without using the converter
//  OBD2 is industry standard, X-Sim will additionally expand the OBD2 PID with gear and other values
//
//  Usage:
//  Arduino has to be connected to a free USB port on the computer where the extractor is running
//  Open the extractor and open the settings menu, there you have to select the OBD2 menu
//  Add now your arduino comport to the OBD2 list.
//  After closing the dialog you will see the arduino LED will be enabled which represents receiving data.
//  After closing the extractor application the LED will switch off.
//  Use this code to insert your own display code at the fitting positions
//  Copyright 2013 Martin Wiedenbauer, X-Sim.de
//
//  References:
//  http://en.wikipedia.org/wiki/OBD-II_PIDs
//  http://elmelectronics.com/DSheets/ELM327DS.pdf
//  http://www.x-sim.de


bool extractordetected=false;   //Will get updated from last positive or negative receive
int receivebuffer[20]={0};      //Receive buffer

void setup()
{
   pinMode(13, OUTPUT); //Arduino UNO LED off
   digitalWrite(13, LOW);
   Serial.begin(9600);

   //Do here stuff to init display and zero to default



}

int HexToInt(int c)
{
   if (c >= '0' && c <= '9') 
   {
      return c - '0';
   } 
   else if (c >= 'a' && c <= 'f') 
   {
      return c - 'a' + 10;
   } 
   else if (c >= 'A' && c <= 'F') 
   {
      return c - 'A' + 10;
   } 
   else 
   {
      return -1; // getting here is bad: it means the character was invalid
   }
}

int ParseReceiveBuffer(int commandhighbyte, int commandlowbyte, int receivelength)
{
   //First character is removed of the receivebuffer string and must not be verified again
   if( receivebuffer[0]=='1' && receivebuffer[2]==commandhighbyte && receivebuffer[3]==commandlowbyte )
   {
      //Parse 2 byte values on position 5 and 6 in the buffer string
      if(receivelength==7)
      {
         int highresult=HexToInt(receivebuffer[5]);
         int lowresult =HexToInt(receivebuffer[6]);
         if(highresult==-1 || lowresult==-1){return -1;}
         return ((16*highresult) + lowresult);
      }
      //Parse 4 byte values on position 5,6,8 and 9 in the buffer string
      if(receivelength==10)
      {
         int tophighresult=HexToInt(receivebuffer[5]);
         int toplowresult =HexToInt(receivebuffer[6]);
         int highresult=HexToInt(receivebuffer[8]);
         int lowresult =HexToInt(receivebuffer[9]);
         if(tophighresult==-1 || toplowresult==-1 || highresult==-1 || lowresult==-1){return -1;}
         return ((4096*tophighresult) + (256*toplowresult) + (16*highresult) + lowresult);
      }
   }
   return -1; //Something is wrong with the returned OBD2 echo command byte
}

//This function will wait for the first character in receivetrigger and will parse the result
int ReceiveValueWithTimeout(int receivetrigger, int commandhighbyte, int commandlowbyte, int receivelength)
{
   int arduinoserialbuffer=0;
   int buffercount=-1;
   for(int z=0; z < 1500; z++) //1500ms timeout should be enough
   {
      while(Serial.available())
      {
         if(buffercount==-1)
         {
            arduinoserialbuffer = Serial.read();
            if(arduinoserialbuffer != receivetrigger) //Wait until the trigger is reached, ignore echo, first character is not in the buffer
            {
               buffercount=-1;
            }
            else
            {
               buffercount=0;
            }
         }
         else
         {
            arduinoserialbuffer = Serial.read();
            receivebuffer[buffercount]=arduinoserialbuffer;
            buffercount++;
            if(buffercount > receivelength) //buffer has now waitlen character length
            {
               return ParseReceiveBuffer(commandhighbyte, commandlowbyte, receivelength);
               buffercount=-1;
            }
         }
      }
      delay(1);
   }
   return -1;
}

void ClearReceiveBuffer()
{
    while(Serial.available())
    {
        Serial.read();
    }
}

void SendEchoDisabled() //not used here and a part of the OBD2 ELM327 specifications, as INFO
{
   //ATE0 Echo disabled
   Serial.write('A');
   Serial.write('T');
   Serial.write('E');
   Serial.write('0');
   Serial.write('\r');
}

//010c Request RPM, remember:  OBD2 RPM is ((A*256)+B)/4
int GetOBD2RpmValue()
{
   //010c
        ClearReceiveBuffer();
   Serial.write('0');
   Serial.write('1');
   Serial.write('0');
   Serial.write('c');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','0','C',10);
}

//010d Request speed in kmh
int GetOBD2SpeedValue()
{
   //010d
   ClearReceiveBuffer();
   Serial.write('0');
   Serial.write('1');
   Serial.write('0');
   Serial.write('d');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','0','D',7);
}

//01e0 Request gear number
int GetOBD2GearValue()
{
   //01e0
   ClearReceiveBuffer();
   Serial.write('0');
   Serial.write('1');
   Serial.write('e');
   Serial.write('0');
   Serial.write('\r');
   return ReceiveValueWithTimeout('4','E','0',7);
}

void loop()
{
   int speed=0;
   int rpm=0;
   int gear=GetOBD2GearValue();
   while(gear >= 0)
   {
      if(extractordetected==false)
      {
         SendEchoDisabled();   //Will cause a OK\r as answer from the extractor, ignored in this code
         extractordetected=true;
      }
      //Read all values
      gear = GetOBD2GearValue(); //Notice: offset +1 because of reverse gear
      speed= GetOBD2SpeedValue();
      rpm  = GetOBD2RpmValue();
                rpm=rpm/4 ; //remember OBD2 RPM is ((A*256)+B)/4
      if(gear!=-1 && speed!=-1 && rpm!=-1)
      {
         digitalWrite(13, HIGH); //We have connection and all values are ok, turn on the LED
         //Do here your LCD or display stuff




      }
   }
   extractordetected=false;
   digitalWrite(13, LOW); //No connection, turn off the LED

   //Do here stuff to set display to zero or default




   delay(2000); //No serial connection, poll serial port all two seconds + readtimeout until a running extractor is detected
}

Wo siehst Du Probleme? I2C und SPI lassen sich unabhängig voneinander benutzen, und solange nur Änderungen an die Anzeigen übertragen werden, gibt es keine Probleme mit Timern oder dem Timing.

Ich bin jetzt ein Stück weiter.
Das LCD und das Dot Matrix laufen wie sie sollen.

Das 7 Segment ist im Code auch nutzbar. Nur Leider kriege ich es nicht das Drehzahl und Geschwindigkeit auf dem 7 Segment angezeigt werden. Folgendes habe ich

Auf den linken 4 Stellen wollte ich die Drehzahl haben, und auf den 3 rechten dann die Geschwindigkeit.

Ich poste mal meinen Code

    //Read all values
    gear = GetOBD2GearValue(); //Notice: offset +1 because of reverse gear
    speed= GetOBD2SpeedValue();
    rpm  = GetOBD2RpmValue();
                rpm=rpm/4;
    if(gear!=-1 && speed!=-1 && rpm!=-1)
    {
      digitalWrite(13, LOW); //We have connection and all values are ok, turn on the LED
      //Do here your LCD or display stuff
                        char* neutral = "n";                // sets the character for neutral
                        char* reverse = "r";                // sets the character for reverse
                        //
                        if (gear==0){
                        sprintf(message,"%s:%s %s:%5d",rapport, reverse , trmin, rpm);
                        sprintf(message1,"%s:%3d %s",speed1, speed , speedunit);
                        lcd.setCursor(0,0);
                        lcd.write(message); //envoi le message sur l'écran 1 ere ligne
                        lcd.setCursor(0,1);
                        lcd.write(message1); //envoi le message sur l'écran 2 eme ligne
                        mydisplay.setRow(0,0,B11111111);                                   
                        mydisplay.setRow(0,1,B11111111);
                        mydisplay.setRow(0,2,B11111111);
                        mydisplay.setRow(0,3,B00011011);
                        mydisplay.setRow(0,4,B00011011);
                        mydisplay.setRow(0,5,B11111111);
                        mydisplay.setRow(0,6,B11111111);
                        mydisplay.setRow(0,7,B11101110);
                        mydisplay.setDigit(1, 7, rpm, false);
                        mydisplay.setDigit(1, 2, speed, false);
                        }
                        
                        if (gear==1){
                        sprintf(message,"%s:%s %s:%5d",rapport, neutral , trmin, rpm);
                        sprintf(message1,"%s:%3d %s",speed1, speed , speedunit);
                        lcd.setCursor(0,0);
                        lcd.write(message); //envoi le message sur l'écran 1 ere ligne
                        lcd.setCursor(0,1);
                        lcd.write(message1); //envoi le message sur l'écran 2 eme ligne
                               mydisplay.setRow(0,0,B11111111);
                        mydisplay.setRow(0,1,B11111111);
                        mydisplay.setRow(0,2,B11111111);
                        mydisplay.setRow(0,3,B00111110);
                        mydisplay.setRow(0,4,B01111000);
                        mydisplay.setRow(0,5,B11111111);
                        mydisplay.setRow(0,6,B11111111);
                        mydisplay.setRow(0,7,B11111111);
                        mydisplay.setDigit(1, 7, rpm, false);
                        mydisplay.setDigit(1, 2, speed, false);
                        
                        
                        }
                        if (gear >= 2 and gear <10 ){
                        sprintf(message,"%s:%d %s:%5d",rapport, gear-1 , trmin, rpm);
                        sprintf(message1,"%s:%3d %s",speed1, speed , speedunit);
                        lcd.setCursor(0,0);
                        lcd.write(message); //envoi le message sur l'écran 1 ere ligne
                        lcd.setCursor(0,1);
                        lcd.write(message1); //envoi le message sur l'écran 2 eme ligne
                        mydisplay.setDigit(1, 7, rpm, false);
                        mydisplay.setDigit(1, 2, speed, false);
                        
                        }
                        if (gear==2){
                        mydisplay.setRow(0,0,B00000000);                                   
                        mydisplay.setRow(0,1,B00000100);
                        mydisplay.setRow(0,2,B00000110);
                        mydisplay.setRow(0,3,B11111111);
                        mydisplay.setRow(0,4,B11111111);
                        mydisplay.setRow(0,5,B11111111);
                        mydisplay.setRow(0,6,B00000000);
                        mydisplay.setRow(0,7,B00000000);
                        
                        
                        }
                        if (gear==3){
                        mydisplay.setRow(0,0,B11100110);                                   
                        mydisplay.setRow(0,1,B11100111);
                        mydisplay.setRow(0,2,B11100111);
                        mydisplay.setRow(0,3,B11110111);
                        mydisplay.setRow(0,4,B11010011);
                        mydisplay.setRow(0,5,B11010011);
                        mydisplay.setRow(0,6,B11001111);
                        mydisplay.setRow(0,7,B11000110);
                        
                        }
                        if (gear==4){
                        mydisplay.setRow(0,0,B11011011);                                   
                        mydisplay.setRow(0,1,B11011011);
                        mydisplay.setRow(0,2,B11011011);
                        mydisplay.setRow(0,3,B11011011);
                        mydisplay.setRow(0,4,B11011011);
                        mydisplay.setRow(0,5,B11111111);
                        mydisplay.setRow(0,6,B11111111);
                        mydisplay.setRow(0,7,B01100110);
                        
                        }
                        if (gear==5){
                        mydisplay.setRow(0,0,B00011111);                                   
                        mydisplay.setRow(0,1,B00111111);
                        mydisplay.setRow(0,2,B00011111);
                        mydisplay.setRow(0,3,B00011000);
                        mydisplay.setRow(0,4,B11111111);
                        mydisplay.setRow(0,5,B11111111);
                        mydisplay.setRow(0,6,B11111111);
                        mydisplay.setRow(0,7,B00011000);
                        
                        }
                        if (gear==6){
                        mydisplay.setRow(0,0,B01011111);                                   
                        mydisplay.setRow(0,1,B11011111);
                        mydisplay.setRow(0,2,B11011111);
                        mydisplay.setRow(0,3,B11011011);
                        mydisplay.setRow(0,4,B11011011);
                        mydisplay.setRow(0,5,B11111011);
                        mydisplay.setRow(0,6,B11111011);
                        mydisplay.setRow(0,7,B01110011);
                        
                        }
                        if (gear==7){
                        mydisplay.setRow(0,0,B01111110);                                   
                        mydisplay.setRow(0,1,B11111111);
                        mydisplay.setRow(0,2,B11111111);
                        mydisplay.setRow(0,3,B11011011);
                        mydisplay.setRow(0,4,B11011011);
                        mydisplay.setRow(0,5,B11011011);
                        mydisplay.setRow(0,6,B11111011);
                        mydisplay.setRow(0,7,B01110010);
                        
                        }
    }
  }
  extractordetected=false;
  digitalWrite(13, HIGH); //No connection, turn off the LED

  //Do here stuff to set display to zero or default
        
        lcd.setCursor(0,0);
        lcd.write("    Keine    ");
        lcd.setCursor(0,1);
        lcd.write("   Verbindung");
        mydisplay.setRow(0,0,24);
        mydisplay.setRow(0,1,36);
        mydisplay.setRow(0,2,90);
        mydisplay.setRow(0,3,153);
        mydisplay.setRow(0,4,153);
        mydisplay.setRow(0,5,90);
        mydisplay.setRow(0,6,36);
        mydisplay.setRow(0,7,24);

delay(2000); //No serial connection, poll serial port all two seconds + readtimeout until a running extractor is detected
        lcd.clear();
}

Aus dem Code ist nicht ersichtlich, welcher Teil funktioniert und welcher nicht.

Kannst Du die Daten nicht irgendwo anzeigen (Serial Monitor...), damit wenigstens klar ist, ob die Werte angekommen sind?

if (gear==0){
sprintf(message,"%s:%s %s:%5d",rapport, reverse , trmin, rpm);
sprintf(message1,"%s:%3d %s",speed1, speed , speedunit);
lcd.setCursor(0,0);
lcd.write(message); //envoi le message sur l'écran 1 ere ligne
lcd.setCursor(0,1);
lcd.write(message1); //envoi le message sur l'écran 2 eme ligne
mydisplay.setRow(0,0,B11111111);
mydisplay.setRow(0,1,B11111111);
mydisplay.setRow(0,2,B11111111);
mydisplay.setRow(0,3,B00011011);
mydisplay.setRow(0,4,B00011011);
mydisplay.setRow(0,5,B11111111);
mydisplay.setRow(0,6,B11111111);
mydisplay.setRow(0,7,B11101110);
mydisplay.setDigit(1, 7, rpm, false);
mydisplay.setDigit(1, 2, speed, false);
}

Mit mydisplay setdigit soll er mir auf dem 7 Segment was anzeigen. rpm und speed zeigen mir auf dem dem LCD die richtigen Werte an.

Du mußt natürlich die Zahlen in Ziffernfolgen umwandeln, und die Ziffern anzeigen. Wenn Du's schon benutzst, kannst Du das mit sprintf() machen, wie für das LCD Display.

Wäre dies so richtig?

sprintf(rpm1,"%5d",rpm);
mydisplay.setDigit(1, 0, rpm1, false);

oder

mydisplay.setDigit(1, 0, ((int) rpm), false);

rpm ist ein String, der nach sprintf() mehrere Ziffern enthält. Jede Ziffer muß einzeln an die richtige Stelle im Display geschickt werden. Dabei muß (vermutlich) auch noch jedes ASCII Zeichen in den Wert der Ziffer konvertiert werden, z.B. mit (rpm*-'0').*
Gibt es denn keine brauchbaren Beispiele zu der MAX7219 Bibliothek?

DrDiettrich:
Gibt es denn keine brauchbaren Beispiele zu der MAX7219 Bibliothek?

Womit ich dienen könnte wäre ein Sketch, wo der Ersteller einen TM1638 benutzt.
Aber das sind alles Sachen die momentan noch weit über meinem Horizont liegen.

Du kannst ja auch im Forum suchen, wie andere Leute Zahlen in Ziffern umwandeln, um sie auf 7-Segment Displays auszugeben.