Tableau de bord pour moto

Bonjour tout le monde !
J'ai profité de m'être mangé une voiture avec mon chopper pour le customiser (to chop it, comme disent les amerloc) en remplaçant les pièces mortes pendant le crash. Malheureusement, le compteur aussi avait souffert. Et l'arduino m'a permis d'en faire un nouveau.

Tout le soucis était dans le fait de rendre tout ça compacte.
On a donc :
Un compteur de vitesse
Une horloge
Une sonde de température ambiante
Une sonde de température moteur (y'a pas de radiateur sur cette moto)
Une jauge à essence
Et une carte sd pour stocker le nombre de kilomètre du moteur.

Vous pouvez retrouver le fil de discussion ici.

1 Like

Pour ceux qui ont aimé ce projet, vous pouvez me soutenir sur le petit concours semageek.
Ici => http://www.semageek.com/edito-du-02-mai-2013-le-carton-cest-la-vie/

Bon, je viens de finir de coder la V2.0 du compteur. J'avais un petit soucis avec le capteur à effet hall : au dessus de 100km/h environ, il loupait des tours de roue. Donc ma vitesse affichée faisait des "bonds" (74, 101, 122...) alors que je restais a vitesse constante.
J'ai donc pris une puce GPS (MT3339) qui me donne du coup quelques infos supplémentaires (comme l'heure, j'ai viré aussi le module RTC du coup).
J'ai aussi viré la jauge à essence, parce que trop de code et trop de fils, fallait que ça rentre dans un arduino mini et dans l'emplacement du compteur sur la moto. Du coup j'ai gagné en place sur l’écran, je peux maintenant afficher la distance parcourue (avant je ne l'affichait que pendant l'initialisation).
Des tas de soucis pour passer en dessous des 28 600KB, mais j'ai enfin réussi, et ça fonctionne !

Voici le code, et une vidéo du truc en marche bientôt, quand j'aurais remonté le tout.

// Inclusion des librairies
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 4, 5, 6, 7, 8); // Initialisation de la librairie Liquid Crystal
#include <SD.h>
#include <Adafruit_MAX31855.h>
/*-----------------------------------------------------------------------------------
 ============================GPS======================================================
 -----------------------------------------------------------------------------------*/
#include <TinyGPS.h>
TinyGPS gps;
SoftwareSerial nss(A4, A5);
unsigned long chars;
unsigned short sentences, failed;
char b;
float flat, flon;
unsigned long age;
int year;
byte month, day, hour, minute, second, hundredths;
bool newData;
int z = 0;
/*-----------------------------------------------------------------------------------
 ============================GPS=END==================================================
 -----------------------------------------------------------------------------------*/
byte NO[8] = { 
  B11110,
  B11000,
  B10100,
  B10010,
  B00001,
  B00000,
  B00000,
  B00000 }; 
byte N[8] = { 
  B00100,
  B01110,
  B10101,
  B00100,
  B00100,
  B00000,
  B00000,
  B00000 }; 
byte NE[8] = { 
  B01111,
  B00011,
  B00101,
  B01001,
  B10000,
  B00000,
  B00000,
  B00000 }; 
byte E[8] = { 
  B00100,
  B00010,
  B11111,
  B00010,
  B00100,
  B00000,
  B00000,
  B00000 }; 
byte SUDEST[8] = { 
  B10000,
  B01001,
  B00101,
  B00011,
  B01111,
  B00000,
  B00000,
  B00000 };  
byte S[8] = { 
  B00100,
  B00100,
  B10101,
  B01110,
  B00100,
  B00000,
  B00000,
  B00000 }; 
byte SO[8] = { 
  B00001,
  B10010,
  B10100,
  B11000,
  B11110,
  B00000,
  B00000,
  B00000 }; 
byte O[8] = { 
  B00100,
  B01000,
  B11111,
  B01000,
  B00100,
  B00000,
  B00000,
  B00000 }; //*/

const int tmpPin = A0;    // Selection de l'entrée analogique pour la sonde température TMP36

unsigned int intVitesse=0; // initialisation de la vitesse à afficher (int)
unsigned long previousMillis = 0;      
const int interval = 3000; // interval de defilement des parametres sur le lcd
int lcdState = 0;  // parametre en cours d'affichage
int kmState = 0;
float kmcount;
int intkm;
char kmprev[10]; // tableau pour lire la carte SD
int bufPos = 0; // buffer pour lire la carte SD
char byteIn = 0; // byte de la carte SD
float lastLat=0;
float lastLon=0;


short unsigned int val=0;
String unite="N/C";




// Initialize the Thermocouple
Adafruit_MAX31855 thermocouple(A1, A2, A3);

void enregistrer(int km)
{
  File dataFile = SD.open("datalog.txt", FILE_WRITE); // on ecrit le nombre de km parcourus dans un fichier
  // if the file is available, write to it:
  if (dataFile) 
  {
    dataFile.seek(0);
    dataFile.print(km);
    dataFile.close();
  }
  // if the file isn't open, pop up an error:
  //*/
}

PS : merci à ceux qui ont voté pour moi sur semageek, j'ai gagné un bon d'achat et me suis acheté un raspberryPi avec :slight_smile:

1 Like
void setup() 
{
  //Serial.begin(115200);
  nss.begin(9600);

  // Configuration de l'afficheur 16 caractères en 2 lignes 
  lcd.begin(16, 2);
  // creation des caracteres speciaux

  lcd.createChar(8, NO);
  lcd.createChar(1, N);
  lcd.createChar(2, NE);
  lcd.createChar(3, E);
  lcd.createChar(4, SUDEST);
  lcd.createChar(5, S);
  lcd.createChar(6, SO);
  lcd.createChar(7, O);//*/


  lcd.clear();

  lcd.print("Init");
  delay(100);


  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (SD.begin(10)) 
  {
    memset(kmprev,0,sizeof(kmprev)); 
    // on lit le nombre de km parcouru jusqu'ici
    File dataFile = SD.open("datalog.txt");
    // if the file is available, write to it:
    if (dataFile) 
    {
      while (dataFile.available()) 
      {
        byteIn = dataFile.read();
        if (bufPos < sizeof(kmprev))
          kmprev[bufPos++] = byteIn;
      }
      dataFile.close();
      kmcount = strtod(kmprev, NULL);
      delay(100);
    }  
    // if the file isn't open, pop up an error:

  }
  else 
  {
    lcd.setCursor(0, 1);
    lcd.print("SD");
    delay(500);
  }//*/

  newData = false;
  lcd.clear();
  lcd.print("No GPS");
  // For one second we parse GPS data and report some key values
  while (newData==false)
  {
    while (nss.available())
    {
      b = nss.read();
      //Serial.write(b); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(b)) 
      {
        // Did a new valid sentence come in?
        newData = true;
        gps.f_get_position(&flat, &flon, &age);
        lastLat=flat;
        lastLon=flon;
      }
    }
  }
  lcd.clear();

  delay(10);
}




void loop() 
{
  /*-----------------------------------------------------------------------------------
   ============================GPS======================================================
   -----------------------------------------------------------------------------------*/
  newData = false;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (nss.available())
    {
      b = nss.read();
      //Serial.write(b); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(b)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData == true)
  {
    gps.f_get_position(&flat, &flon, &age);


    intVitesse=(gps.f_speed_kmph())*1.10;

    if (kmState>=5) 
    {
      kmcount=kmcount+(TinyGPS::distance_between(flat, flon, lastLat, lastLon) / 1000);
      kmState=0;
      lastLat=flat;
      lastLon=flon;
      intkm = kmcount;
      enregistrer(intkm);
    }

    /*-----------------------------------------------------------------------------------
     ============================GPS=END==================================================
     -----------------------------------------------------------------------------------*/


    //bigFont(intVitesse); // affichage de la vitesse en gros, fonctionne seulement si inferieur a 999!

    //lcd.print("Km/h");

    String point = TinyGPS::cardinal(gps.f_course());
    lcd.setCursor(0, 0);
    delay(10);

    if (point.equalsIgnoreCase("NO")) 
    {
      lcd.write(2);
    }
    else if (point.equalsIgnoreCase("NE")) 
    {
      lcd.write(8);
    }
    else if (point.equalsIgnoreCase("E")) 
    {
      lcd.write(7);
    }
    else if (point.equalsIgnoreCase("SE")) 
    {
      lcd.write(6);
    }
    else if (point.equalsIgnoreCase("S")) 
    {
      lcd.write(5);
    }
    else if (point.equalsIgnoreCase("SO")) 
    {
      lcd.write(4);
    }
    else if (point.equalsIgnoreCase("O")) 
    {
      lcd.write(3);
    }
    else
    {
      lcd.write(1);
    }


    delay(10);

    // on gere l'affichage des options heure et temperature
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) 
    {
      lcdState ++;
      previousMillis = currentMillis;   
    }


    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);


    switch (lcdState) 
    {
    case 1: 
      val = gps.satellites();
      unite = (" Sat");
      break;

    case 2: 
      unite = ("'A ");
      val = (( (float) ((((float)(analogRead(tmpPin)))*5000.0)/1023.0) - 500.0) /10.0);
      break;


    default: 
      kmState++;
      unite = ("'M ");
      val=thermocouple.readCelsius();
      lcdState = 0;
    }

    //sprintf(ligneA, "%03dkm/h %02d:%02d", intVitesse , hour+2, minute);
    //sprintf(ligneB, "%dkm %d%s", intkm, val, unite);
    String ligneA=" ";
    String ligneB="";
    ligneA += showDigits(intVitesse, 3);
    ligneA += "km/h  ";
    ligneA += showDigits(hour+2, 2);
    ligneA += ":";
    ligneA += showDigits(minute, 2);
    ligneB += showDigits(intkm, 5);
    ligneB += "km   ";
    ligneB += showDigits(val, 2);
    ligneB += unite;
    lcd.print(ligneA);
    Serial.println(ligneA);
    delay(10);
    lcd.setCursor(0, 1);
    delay(10);
    lcd.print(ligneB);
    Serial.println(ligneB);
    delay(10);
    lcd.home();

  }

  delay(40);
}

String showDigits(int digits, int n)
{
  String string;
  // utility function for digital clock display: prints leading 0
  if(digits < 1)
  {
    for (int r=0; r<n; r++)
    {
      string += '0';
    }
  }
  else if(digits < 10)
  { 

    for (int r=0; r < (n-1); r++)
    {
      string += '0';
    }
    string += digits;
  }
  else if(digits < 100)
  {
    for (int r=0; r < (n-2); r++)
    {
      string += '0';
    }
    string += digits;
  }
  else if(digits < 1000)
  {
    for (int r=0; r < (n-3); r++)
    {
      string += '0';
    }
    string += digits;
  }
  else if(digits < 10000)
  {
    for (int r=0; r < (n-4); r++)
    {
      string += '0';
    }
    string += digits;
  }
  else if(digits < 100000)
  {
    for (int r=0; r < (n-5); r++)
    {
      string += '0';
    }
    string += digits;
  }
  else
  {
    string += digits;
  }

  return string;
}

Salut,

Pourquoi une carte SD? l'EEPROM ne suffit pas? ça te ferait gagner un max en programmation...

Pour le nombre de cycle d'écriture. Si la SD à atteint le sien, je la change. Pour l'arduino... Mais je pourrais très bien utiliser une eeprom externe !