LOCODUINO

Parlons Arduino => Vos projets => Discussion démarrée par: Escargot le octobre 12, 2020, 01:49:47 pm

Titre: Boite de mesure de vitesse Arduino
Posté par: Escargot le octobre 12, 2020, 01:49:47 pm
Bonjour,

Tout nouvel inscrit, je viens ici pour trouver de l'aide pour un nouveau projet.

Je réalise un nouvel outil de mesure (nous en avons déjà plusieurs) pour le paramétrage des CV 2, 5, 6, 3 et 4. Les précédents sont utilisés avec la motrice roulant sur un réseau, avec ce nouveau projet les mesures se font sur un banc test. La grande roue va être indexée avec 20 aimants, un capteur ILs, un Arduino et un écran pour l'affichage de la vitesse et de la distance. Il me faut donc un programme qui calcule la vitesse au 1/87 en faisant une moyenne des impulsions de l'ILs et qui affiche le résultat sur un écran de 4 lignes pour 20 caractères.


J'ai acheté :
Un Itsy Bitsy (https://letmeknow.fr/shop/fr/cartes-compatibles/1750-itsy-bitsy-32u4-5v-0791954231922.html) 32u4 5V Référence Adafruit : 3677 (pour remplacer un Arduino Nano indisponible)
un capteur magnétique (https://letmeknow.fr/shop/fr/autres/513-capteur-de-magnetisme-652733136176.html)
Un afficheur LCD 4 lignes 20 caractères bleu I2C (https://letmeknow.fr/shop/fr/ecrans/185-afficheur-lcd-4-lignes-20-caracteres-bleu-i2c-4894479443361.html)
20 petits aimants qui seront collés autour de la grande roue et qui activeront l'ILs

L'un de vous aurait-il la possibilité de me faire le programme :)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le octobre 12, 2020, 02:04:31 pm
La suite...

Sur cette base, pensez-vous qu'il soit possible de régler les Cv 3 et 4 ?

Il faudrait que l'on puisse mesurer la distance parcourue à partir de la mise en route de la motrice jusqu'à stabilisation de la vitesse pour le CV 3
et
Que l'on mesure la distance parcoure à partir du moment où la vitesse baisse et jusqu'à l'arrêt pour le CV 4
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Tony04 le octobre 12, 2020, 02:55:38 pm
Bonjour "Escargot",

avez-vous lu cet article ? https://www.locoduino.org/spip.php?article147

Il ne répond certainement pas à votre attente d'un programme tout fait mais peut peut-être vous faire avancer un peu.

Cordialement
Antoine
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le octobre 12, 2020, 03:08:23 pm
Bonjour Tony04,

En fait, nous avons déjà un compteur de vitesse qui reprend cette idée, mais divisé en deux éléments
Un wagon mesureur avec un aimant sur essieux, un ILs, un Arduinon Nano qui calcule, un transmetteur WiFi => Un récepteur WiFi et un écran qui affiche les valeurs transmises par le wagon.

Nous avons donc deux programmes, l'un pour le wagon et l'autre pour l'afficheur, ils sont ICI (https://drive.google.com/drive/folders/1cWb7v9wSIp8C6Oc1MfPe35p_R8Z4-K9J?usp=sharing)

Dans ce nouveau projet, c'est un peu la même chose, sans transmission et surtout, en souhaitant ajouter de quoi évaluer les CV 3 et 4, ce qui est inhabituel ;)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le octobre 12, 2020, 03:17:10 pm
Le wagon :

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

#include <avr/wdt.h>
   
/*
* Arduino Wireless Communication Tutorial
*     Example 1 - Transmitter Code
*               
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/

//--------------------------------------------------------------------------------------------------
// v0   | 1st version with send of default value in increment of 1000 to check "portée"
// v2   | 2nd version + bugs correction
// v3   | Add TX power selection and Baud Rate
//      | Cannaux WiFi utilisable en France: canal 1 à 13 (F=2.412 à 2.472GHz, par pas de 5MHz)
//--------------------------------------------------------------------------------------------------


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";

// PA
#define SENSOR_IN 2   // capteur roue
#define RADIO_TX  4   // LED Radio Tx

#define CFG_PW0   14
#define CFG_PW1   15
#define CFG_BR    16
#define CFG_CH    17


int timeCnt, time0, timet;
int speed;
int speedTab[8];
long speedAvg;
unsigned char tabPt;

float diam = 11.6;   // diametre roue (mm): mesurée pa LJ 11.6mm
float Pi = 3.1416;
float scale = 87;
//float K = (diam * Pi * scale * 3600 * 1000)/(1000 * 1000);   // to convert speed in mm/s (HO) to km/h reel
float K = (diam * Pi * scale * 3.6);   // to convert speed in mm/s (HO) to km/h reel
float fspeed;

int NbPulse;
unsigned char sensorLevel, newSensorLevel;


void setup() {

  //wdt_disable();
  pinMode (CFG_PW0,INPUT_PULLUP);   // Config
  pinMode (CFG_PW1,INPUT_PULLUP);   // Config
  pinMode (CFG_BR,INPUT_PULLUP);    // Config
  pinMode (CFG_CH,INPUT_PULLUP);    // Config

  char TxPower = 0;
  if(digitalRead(CFG_PW0) == 0)  TxPower += 1;
  if(digitalRead(CFG_PW1) == 0)  TxPower += 2;
 
 
  radio.begin();                      // Begin operation of the chip. Call this in setup(), before calling any other methods.

  radio.openWritingPipe(address);     // Open a pipe for writing via byte array
   
  //radio.setPALevel(RF24_PA_MAX);      // Set Power Amplifier (PA) level to one of four levels: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
  radio.setPALevel(TxPower);      // Set Power Amplifier (PA) level to one of four levels: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
 
  if(digitalRead(CFG_BR) == 0) radio.setDataRate(RF24_250KBPS);      // (by default: 1MBds) Fast enough.. Better range
  if(digitalRead(CFG_CH) == 0) radio.setChannel(108);              // (by default: 2.476GHz), F = 2508MHz, = channel Above most Wifi Channels
 
  radio.stopListening();

  pinMode (SENSOR_IN,INPUT_PULLUP);   // Capteur roue
  sensorLevel = digitalRead(SENSOR_IN);
 
  pinMode (RADIO_TX,OUTPUT);        // Measure Tx Time
  digitalWrite(RADIO_TX, 0);
 
  time0 = millis();
  speed = 0;
  for(tabPt = 0; tabPt < 8; tabPt++)
    {
      speedTab[tabPt] = 0;
    }
  tabPt = 0;

  NbPulse = 0;

  //wdt_reset();
  //wdt_enable(WDTO_8S);
 
}

void loop() {
 
  newSensorLevel = digitalRead(SENSOR_IN);
  timet = millis();
  timeCnt = timet - time0;
 
  if((sensorLevel == 0) && (newSensorLevel == 1))
      {
      sensorLevel = 1;

      if(NbPulse == 0)
      {
        time0 = timet;
        timeCnt = 0;
      }
      NbPulse++;

      if(timeCnt > 1000)
          {
          NbPulse--;                            // v1.1
          fspeed = (K * NbPulse) / timeCnt;
          speed = (int)fspeed;
         
          // averaging:

          speedTab[tabPt++] = speed;
          if(tabPt > 7) tabPt = 0;
   
          speedAvg = 0;
          for(unsigned char idx = 0; idx < 8; idx++)
            {
              speedAvg += speedTab[idx];
            }
   
          speedAvg = ((speedAvg << 16) & 0xFFFF0000) + speed;   // divide by 8 equal >> 3

          digitalWrite(RADIO_TX, 1);
          radio.write(&speedAvg, sizeof(speedAvg));           // Write for single NOACK writes. Optionally disables acknowledgements/autoretries for a single write.
          digitalWrite(RADIO_TX, 0);

          speed = 0;
          NbPulse = 0;
          }
      }
  else
      {
      sensorLevel = newSensorLevel;

      if(timeCnt > 2000)
          {
           // averaging:
          speedTab[tabPt++] = 0;
          if(tabPt > 7) tabPt = 0;
   
          speedAvg = 0;
          for(unsigned char idx = 0; idx < 8; idx++)
            {
              speedAvg += speedTab[idx];
            }
   
          speedAvg = ((speedAvg << 16) & 0xFFFF0000) + speed;   // divide by 8 equal >> 3

          digitalWrite(RADIO_TX, 1);
          radio.write(&speedAvg, sizeof(speedAvg));           // Write for single NOACK writes. Optionally disables acknowledgements/autoretries for a single write.
          digitalWrite(RADIO_TX, 0);
         
          time0 = timet;

          if((speed > 0) && (speed < 1000));     // if calculated speed: do nothing
          else                                   // no speed
            {
              speed += 1000;
              if (speed >= 10000) speed = 0;
            }
         }
      }

   delay(5);        // PA v1.1
}

L'afficheur :

/*
* Arduino Wireless Communication Tutorial
*       Example 1 - Receiver Code
*               
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";


#define CFG_PW0   14
#define CFG_PW1   15
#define CFG_BR    16
#define CFG_CH    17


int speed;
long speedAvg;
long SpeedAvg_Table[4];
float speedMoy;




#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display






void setup() {

  pinMode (CFG_PW0,INPUT_PULLUP);   // Config
  pinMode (CFG_PW1,INPUT_PULLUP);   // Config
  pinMode (CFG_BR,INPUT_PULLUP);    // Config
  pinMode (CFG_CH,INPUT_PULLUP);    // Config


 
  Serial.begin(9600);
  radio.begin();
 
  radio.openReadingPipe(0, address);

  //char TxPower = 0;
  //if(digitalRead(CFG_PW0) == 0)  TxPower += 1;
  //if(digitalRead(CFG_PW1) == 0)  TxPower += 2;
  radio.setPALevel(RF24_PA_MIN);

  if(digitalRead(CFG_BR) == 0) radio.setDataRate(RF24_250KBPS);      // (by default: 1MBds) Fast enough.. Better range
  if(digitalRead(CFG_CH) == 0) radio.setChannel(108);              // (by default: 2.476GHz), F = 2508MHz, = channel Above most Wifi Channels

 
  radio.startListening();



  lcd.init();                      // initialize the lcd
  lcd.backlight();
 
 
  //lcd.print("Hello, world!");
 

  lcd.print("  RX_RF24 vers.02a  ");
  lcd.setCursor(0,1);
  lcd.print("   03 / 09 / 2018   ");

  char TxPower = 0;
  if(digitalRead(CFG_PW0) == 0)  TxPower += 1;
  if(digitalRead(CFG_PW1) == 0)  TxPower += 2;

  lcd.setCursor(0,2);
  lcd.print("Tx Pw:");
  lcd.print(TxPower, DEC);
  if(TxPower == 0)      lcd.print("   MIN PA ");
  else if(TxPower == 1) lcd.print("   LOW PA  ");
  else if(TxPower == 2) lcd.print("   HIGH PA ");
  else if(TxPower == 3) lcd.print("   MAX PA  ");
  else                  lcd.print("   ERROR   ");
   
  lcd.setCursor(0,3);
  if(digitalRead(CFG_BR) == 0)  lcd.print("BR=250kBp ");
  else                          lcd.print("BR=1MBp   ");
  if(digitalRead(CFG_CH) == 0)  lcd.print("F=2.508GHz ");
  else                          lcd.print("F=2.476GHz ");

  delay(2000);

  speed = 0;
 
}


void loop() {
  if (radio.available())
    {

    radio.read(&speedAvg, sizeof(speedAvg));
    Serial.print(speedAvg & 0x0000FFFF, DEC);
    Serial.print(" Avg: ");
    speedMoy = speedAvg >> 16;
    speedMoy = speedMoy / 8;
    Serial.println(speedMoy);


    for (int i = 0; i < 3; i++)
        {
            SpeedAvg_Table[i] = SpeedAvg_Table[i+1];
        }
    SpeedAvg_Table[3] = speedAvg;


    lcd.clear();
    lcd.home();

    for (int i = 0; i < 4; i++)
        {
        lcd.setCursor(0,i);
        lcd.print(SpeedAvg_Table[i] & 0x0000FFFF, DEC);
       
        lcd.setCursor(6,i);
        lcd.print(" Avg: ");
       
        speedMoy = SpeedAvg_Table[i] >> 16;
        speedMoy = speedMoy / 8;
        lcd.print(speedMoy);
       
        }
    }
}

Titre: Re : Boite de mesure de vitesse Arduino
Posté par: chris_bzg le octobre 12, 2020, 03:17:29 pm
L'article conseillé par Tony04 n'est à mon avis pas le bon, simplement parce qu'il propose une mesure de la vitesse en un seul endroit du réseau.
Ici, il s'agit de faire la mesure sur un banc d'essai en comptant les impulsions d'un ILS.

Tout d'abord, à cause de ses rebonds, l'ILS n'est pas le meilleur capteur à mon avis. Il vaudrait mieux le remplacer par un capteur à effet Hall, dont le déclenchement est bien plus franc (voir l'article https://www.locoduino.org/spip.php?article273).

Ensuite, comme il s'agit de compter des impulsions générées par la rotation d'une roue, le mieux serait de s'inspirer de cet article https://www.locoduino.org/spip.php?article259.

Ne pratiquant pas le DCC, je ne peux hélas rien dire concernant les Cv 3 et 4, mais beaucoup de gens connaissent bien le sujet.  ;)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Thierry le octobre 12, 2020, 03:56:47 pm
L'un de vous aurait-il la possibilité de me faire le programme :)

Le projet parait sympathique en tout cas. Je souhaiterais ajouter cependant que la politique de ce site, et donc du forum qui va avec, n'est pas de faire le travail à la place des membres, mais bien de donner les clés pour qu'il puisse lui même faire ce travail. Le but du site n'est pas de fournir des programmes clef en main, mais d'aider à comprendre et manipuler les outils pour y arriver, et les explications qui vont avec.

Que les choses soient claires, on ne refuse pas d'aider, bien au contraire, mais fournir un programme tout fait ne correspond pas à la philosophie du site.

En tout cas, on est tous prêt à aider si besoin pour la mise au point !
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Tony04 le octobre 12, 2020, 05:08:22 pm
En effet, l'article proposé par chris_bzg est plus proche de votre projet.
Pour les tests des CV3 et 4 il suffit de tester la stabilisation de la vitesse et enregistrer les positions à ce moment, puis faire les calculs nécessaires.
Titre: Re : Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le octobre 12, 2020, 05:27:18 pm
L'un de vous aurait-il la possibilité de me faire le programme :)

Le projet parait sympathique en tout cas. Je souhaiterais ajouter cependant que la politique de ce site, et donc du forum qui va avec, n'est pas de faire le travail à la place des membres, mais bien de donner les clés pour qu'il puisse lui même faire ce travail. Le but du site n'est pas de fournir des programmes clef en main, mais d'aider à comprendre et manipuler les outils pour y arriver, et les explications qui vont avec.

Que les choses soient claires, on ne refuse pas d'aider, bien au contraire, mais fournir un programme tout fait ne correspond pas à la philosophie du site.

En tout cas, on est tous prêt à aider si besoin pour la mise au point !
Bonjour Thierry,

J'ai au club, car je suis le président du club de Franconville "Le Train d'Enfer (https://traindenfer95.wixsite.com/accueil)", 3 ou 4 membres qui se débrouillent un peu en programmation Arduino (ce qui n'est pas mon cas). Le sujet est déjà dans leurs mains, ils se penchent dessus, ce qui m'a fait venir ici pour poser ces questions est surtout l'idée d'avoir une autre approche :D D'ailleurs, dans les réponse que j'ai déjà eu, deux idées "nouvelles" sont apparues.
A savoir que j'ai aussi un gros site sur les logiciels d'architecture grand public (http://escargot-archi.eu/forum/portal.php) dans lequel j'ai moi aussi souvent la même réponse ::)

J'ai donné le lien de se sujet sur le forum de mon club afin que les copains puissent suivre les idées qui viennent d'ici, je ne doute pas que l'un d'entre eux se fera un plaisir de me faire le programme. Je pose ici des questions complémentaires, certaines fonctions ou possibilités, vos retours sont très intéressant et vont surement nous permettre de faire un bel outil de mesure "statique" qui intéressera surement la communauté.

Voiloù ;)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: msport le octobre 12, 2020, 10:09:11 pm
Bonjour,
bienvenue sur Locoduino qui est, comme vous l'avez bien noté, un site participatif.
Ci-joint, un programme écrit vite fait, mal fait. Néanmoins si vous l'utilisez, vous vous engagez à publier ce que vous en faites sur le forum LOCODUINO.

 *    Cahier des charges, complété par des hypothèses
 *    https://forum.locoduino.org/index.php?topic=1072.0;topicseen
 *
 *    adapté de
 *    https://www.instructables.com/Arduino-Frequency-Counter/
 *   
 *    cablage suivant
 *    https://www.locoduino.org/spip.php?article273 pour le capteur : signal connecté au Pin 3
 *     
 *    et LCD 20x4 I2C : SDA = A4, SCL = A5
 *   
 *    OSSW

PS : un tour sur internet donne les REED capables de commuter au plus à 200 Hz, ce qui fait ~40Km/h avec votre montage, si je ne me suis pas trompé.
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le octobre 26, 2020, 11:15:25 am
Bonjour,

Nous commençons à travailler sur le code, je reviendrais vers vous pour vous faire part de nos avancés.

Nous souhaitons afficher les infos suivantes :
Vitesse d'un aimant à l'autre
Vitesse moyenne sur 3 ou 5 aimants pour les petites vitesses
Vitesse moyenne sur 20 aimants pour les grandes

Distance en mètres réels depuis l'appuie sur le bouton
Distance au 1/87 depuis appuie sur le bouton
Pour les deux distances, est-il possible de figer l'affichage à la deuxième impulsion ? La première reset, la deuxième fige, la suivante reset et ainsi de suite... Le but est de lire le résultat alors que la roue tourne encore 😇

Merci pour vos conseils et avis ;)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: msport le octobre 26, 2020, 10:20:35 pm
Bonsoir,

vos aficionados auront surement plus de difficultés à mettre au point la capture de l'information que de la présenter sur le LCD 4x20 en différentes déclinaisons. Mais il vaudrait mieux leur parler un langage qu'ils comprennent bien, celui du cahier des charges fonctionnel. C'est à dire l'information que vous voudriez avant de donner la solution au problème auquel vous pensez. (par exemple pourquoi 1, 3/5 plutôt que 20 aimants)

De base pour figer l'affichage , il suffit de ne plus le mettre à jour, ça c'est simple !
Et pas compliqué de réinitialiser une variable sur l'appui d'un bouton. C'est probablement un cas d'école pour l'étude d'un compteur.

Plus difficile est de structurer les données qui vous intéressent et comment les décliner.
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le novembre 24, 2020, 10:54:09 pm
Bonjour à tous,

Le projet à bien avancé, la boite est fonctionnelle, les mesures sont hyper précises. Un bouton permet de figer l'affichage pour lecture et ensuite réinitialisation.
Il me reste une petite chose à régler : Sur l'afficheur de 4 lignes, je voudrais que les résultats soient alignés à droite, je ne trouve pas l'astuce qui le permettrait.
L'écran est sous LiquidCrystal_I2C

J'affiche ce qui est en haut, je voudrais ce qui est en bas ::) en faisant en sorte que le décalge se fasse vers la gauche lorsque la valeur à afficher augmente, bien évidemment ;)

(https://i38.servimg.com/u/f38/11/42/55/81/ecran_11.jpg)

Le bout de code qui affiche
if((new_lcd_time - lcd_time) > 1000)
    {
    // speed_avg = (3600 * dist_avg)/(new_lcd_time - lcd_time);           // 3.6 = (3600 sec/h * 1000 ms/sec) / 1000m/km

    lcd.setCursor(0, 0);
    lcd.print("Pulse cnt:          ");
    lcd.setCursor(0, 1);
    lcd.print("Dist.en m:          ");
    lcd.setCursor(0, 2);
    lcd.print("Dist.en km:         ");
    lcd.setCursor(0, 3);
    lcd.print("Vit.moy.:       km/h");

    lcd.setCursor(11, 0);
    lcd.print(pulse_cnt_tot);
     
    lcd.setCursor(13, 1);
    lcd.print(dist_totHO/100);
     
    lcd.setCursor(11, 2);
    lcd.print(dist_tot/1000);
     
    lcd.setCursor(11, 3);
    lcd.print(speed_avg);
     
 #ifdef DEBUG   
     Serial.print("pulse_cnt: ");
     Serial.print(pulse_cnt_tot);
     Serial.print("   - distance_avg (m): ");
     Serial.print(dist_avg);
     Serial.print("   - speed_avg (km/h): ");
     Serial.println(speed_avg);
#endif
     lcd_time = new_lcd_time;
     ref_time_avg = 0;
     dist_avg = 0;
     pulse_cnt = 0;
    }
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: msport le novembre 24, 2020, 11:21:43 pm
Bonsoir,
probablement quelque chose à faire avec :
rightToLeft(void)
à voir dans LiquidCrystal_I2C.cpp
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Thierry le novembre 25, 2020, 08:52:44 am
Jolie réalisation. Pour le cadrage à droite des valeurs, je passerais par le code plutôt que par l'écran. La chaine de caractères devrait être construite avec les valeurs et ensuite envoyée à l'écran. Pour construire la chaine, plusieurs solutions : utiliser un sprintf avec le bon format, ou construire la chaine à la mimine en considérant une virgule fixe pour les distances placée par exemple au caractère 18, et un remplissage des chiffres en extrayant les dizaines au caractère 16, les unités au 17, les dizièmes au 19 etc...
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le novembre 25, 2020, 09:34:12 am
Bonjour,

Nous n'avons pas réussi à trouver la liste et la description des fonctions disponibles dans une librairie  ::) C'est où ?
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: msport le novembre 25, 2020, 10:03:54 am
LiquidCrystal_I2C.cpp

https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library/blob/master/LiquidCrystal_I2C.cpp

C:\Users\Michel\Documents\Arduino\libraries\LiquidCrystal_I2C
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Thierry le novembre 25, 2020, 10:04:33 am
Il n'y a pas de liste des fonctions disponibles. Soit le créateur de la librairie met une doc à disposition comme je le fais (comme dans DCCpp, Commanders, Accessories, etc...), soit il faut regarder dans le fichier .h principal pour savoir de quoi il retourne.
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le décembre 10, 2020, 12:19:58 pm
Bonjour,

J'ai du mieux, j'en suis là  :D

(https://i38.servimg.com/u/f38/11/42/55/81/ecran_12.jpg)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Thierry le décembre 10, 2020, 01:39:10 pm
Bravo, c'est sympa.
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le janvier 04, 2021, 01:13:42 pm
Bonjour,

Bonne année, je vous souhaite de pouvoir retourner dans vos clubs dès que possible, ça devient long  :'(

Petit message pour vous dire que le projet est presque prêt :D Nous sommes maintenant en mesure de faire tous les réglages de base des CV 5-6, 3 et 4 mais en plus, de communiquer avec TrainController ce qui permet de faire la calibration des crans de vitesse des motrices dans TC en moins de 5 mn ;D Les test sont très concluants, précis au 100è de km/h à l'échelle, que du bonheur pour le pilotage automatique ou semi automatique d'un réseau.

Je vais bientôt mettre en ligne les pages dédiées sur notre site web, encore quelques détails à régler  ;)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le janvier 25, 2021, 07:21:11 pm
Bonjour,

Je vous présente mon concept de mesure de vitesses  ;D . Hyper précis, permettant les réglages des CV 2, 5 et 6 par lecture directe de la vitesse ainsi que les 3 et 4 par mesure de la distance parcourue en réel et au 87è.
Compatible avec TrainController V9 pour le calibrage des crans de vitesse :D.

https://traindenfer95.wixsite.com/accueil/conceptdemesure

Concept déposé auprès de FIDEALIS, reproduction pour commercialisation non autorisé  ;)
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le mars 23, 2021, 12:02:23 pm
Bonjour,

Visiblement ce sujet ne fait pas recette :( mais bon, pas grave ;)

Juste pour info à ceux qui ont suivi, nous avons ajouté une nouvelle fonction : Le temps de passage sur une distance de 98cm
Cela permet de mesurer les temps de passage aux différents crans de vitesse pour le paramétrage des UM et autres triplettes dans l'application Z21 de ROCO entre autre.

 ;D
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: msport le mars 23, 2021, 05:12:10 pm
Bonjour,
il est possible que parmi les lecteurs de Locoduino, il n'y ait pas beaucoup d'utilisateurs de Train Controller, qui semble la première cible de ce projet, certes intéressant en soi.
Par ailleurs, il y a une partie mécanique incontournable qui rend la réalisation délicate.
Cordialement
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Dominique le mars 24, 2021, 10:50:09 am
J'ai intégré une mesure de vitesse dans ma centrale DCC afin de déterminer les valeurs des crans correspondant aux vitesses 30, 60 et 90 km/h gérés par mon gestionnaire qui n'est pas RRTC, mais un Arduino !

J'en parle peut-être ici : https://forum.locoduino.org/index.php?topic=290.msg4005#msg4005 (https://forum.locoduino.org/index.php?topic=290.msg4005#msg4005)
Titre: Re : Re : Boite de mesure de vitesse Arduino
Posté par: Jean-Luc le mars 24, 2021, 01:34:07 pm
Visiblement ce sujet ne fait pas recette :( mais bon, pas grave ;)

Bonjour,

Par ici nous somme plutôt dans l'OpenHardware et l'OpenSource. Votre projet n'est ni l'un ni l'autre. Donc bon.

Après je comprends tout à fait que vous soyez dans une démarche commerciale mais à vrai dire j'ai du mal à trouver de l'intérêt pour votre projet n'ayant ni schéma ni code à me mettre sous la dent.

Cordialement
Titre: Re : Re : Re : Boite de mesure de vitesse Arduino
Posté par: savignyexpress le avril 01, 2021, 06:56:22 pm
...Par ici nous somme plutôt dans l'OpenHardware et l'OpenSource....

Bonjour,

Je suis tout à fait d'accord avec ce point de vue. J'ajouterais que l'esprit de Locoduino inclut certainement aussi le partage de connaissances.

La démarche autour de ce projet me surprend. L'auteur commence par poser beaucoup de questions, jusqu'à demander si quelqu'un pourrait écrire le programme.
Ensuite il protège le concept élaboré avec l'aide des membres du forum. Par ailleurs, les conditions auxquelles on peut obtenir le système ne sont pas claires.

Bon week-end de Pâques.
Titre: Re : Boite de mesure de vitesse Arduino
Posté par: Escargot le avril 25, 2021, 12:51:32 pm
Bonjour à tous,

Bon, il semble que je me sois mal expliqué sur mes intentions et que j'ai mis beaucoup trop de temps à venir partager les infos que j'avais, j'en suis navré  :-\

Sachez que ma démarche n'est pas commerciale, j'autorise les particuliers à s'inspirer et même à reproduire, mais j'ai pris le parti de protéger contre la commercialisation, ce n'est pas la même chose. A date, je n'en ai vendu que deux et n'espère pas en vendre beaucoup plus, je ne le fait que pour satisfaire les personnes qui en veulent une mais n'ont pas les connaissance pour le faire eux même. Pour la fabrication, c'est très artisanal, les composants se trouvent sur Ebay très facilement, la quincaillerie vient de Leroy-Merlin et certains éléments sont imprimés en PLA.
Il est tout à fait possible que ça fonctionne avec d'autre TCO que TCV9, mais je ne suis pas en mesure de tester.

N'étant pas moi même programmeur Arduino, je n'ai visiblement pas eu la bonne démarche de partage, j'espère que ce post rétablira un peu les choses.

Pour ceux que ça intéresse encore un peu, voici le code, qui a été écrit par un membre de mon club et pas du tout avec les informations glanées ici. Je partage d'ailleurs les petits bénéfices avec lui ;)
Le seul truc que nous ne sommes pas arrivé à faire, c'est de faire clignoter la LED verte lorsque la vitesse est stabilisée et ce, jusqu'à ce quel se fige allumée. Dans le meilleur des cas elle clignote une fois au début...

//Type de Carte: Adafruit ItsyBitsy 5V
//Port Com:
//Programmer: ArduinoISP

//  NOTE:  OK le 04/11/2020  sur impulsion Arduino 25ms/10ms/75ms --> 120km/h, 300km/h, 40km/h

// NOTE: v10 OK le 28/12/2020, sauf l'envoi vers TC:
//          - ne pas envoyer de 0
//          - envoyer la vitesse une seule fois qaund elle est stabilisée

/****************************************************************************************************************
https://learn.adafruit.com/introducting-itsy-bitsy-32u4/pinouts
https://letmeknow.fr/shop/fr/ecrans/185-afficheur-lcd-4-lignes-20-caracteres-bleu-i2c-4894479443361.html
https://www.arduino.cc/reference/en/language/functions/interrupts/interrupts/

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

 
Blink
D7: capteur input d

Pour les calculs, diamètre des rondelles => 5.88 cm
5.88 x 3.1416 = 18.472608 cm de circonférence
18.47 x 87 = 1606.89 cm => 16,0689 m réels

100km/h / HO <==> 1.15km/h
1.15km/h x 1000m/km / 3600s/h <=> 0.319m/s = 32cm/s

1 tour = 18.47cm
==> 100km/h <--> 1.7tr/s ???????
==> 1.7tr/s / 20 aimants => 1/(1,7 x20)= 29ms entre 2 aimants ??????

pulse 100ms = 2tr = 200km/h

120km/h / HO <==> 1.38km/h
1.38km/h x 1000m/km / 3600s/h <=> 0.38m/s = 38cm/s

==> 120km/h = 2tr/sec
2tr/sec / 20 aimant = 1sec/(2tr x 20 aimants) = 25ms

******************************************************************************************************************/
//======================================================================
// V1.5
// Add 2 LEDs:
// GREEN: flash when speed is stable
// YELLOW: ON when in Freeze
// Ajout du temps pour parcourir 1m a vitesse stabilisée.
//======================================================================

#define FALSE   false
#define TRUE    true
#define LED_BUILTIN 13
#define LED_VERT    8
#define LED_JAUNE   4

#define LED_OFF     0
#define LED_ON      1

#define CAPTEUR_IN_D7 7    // D7 also interrupt pin
#define CAPTEUR_IN_A0 A0

#define SW 11

#define SCL 3
#define SDA 2

#define SENSOR_ON   1
#define SENSOR_OFF  0
bool sensor_state = 0;

unsigned char sw_status, sw_state;
#define COUNT   0
#define FREEZ   1
#define CLEAR   2
#define END_FREEZ   3

//--- v12 ----
#define MIN_SERIAL_TEMPO    10000       // 5 sec = 5000 millisecond
#define MAX_SPEED_ERR       0.10        // 10%

volatile byte sense;
unsigned long ref_time, new_time, delta_t;
unsigned long lcd_time, lcd_new_time, ref_time_avg;
unsigned long serial_time, serial_new_time;           // PA v11

volatile unsigned long pulse_cnt = 0;
volatile unsigned long pulse_cnt_tot = 0;
float speed_i, speed_avg, speed_avg_lcd;               // vitesse instantannée entre 2 aimants, vitesse moyenne par tour, vitesse moyenne pour affichage
float serial_speed_avg, speed_avg_delta, speed_avg_delta_pos, speed_avg_delta_neg;                  // PA v11

//-------------------------------------------------------------------------------------
// Les 3 constantes suivantes sont à ajuster avec le systeme de mesure
//-------------------------------------------------------------------------------------
const float circonf_cm = 18.47;                 // Circonference de la roue de mesure en cm
const int nb_aimants = 20;                      // Nb d'aimants par circonference
const int scale = 87;                               // echelle HO

//------------------- NE pas modifier --------------------------------------------------
float circonf = (circonf_cm * scale) / 100;            // Circonférence réelle en m
float interval = circonf / nb_aimants;                 // Intervale entre 2 aimants en m.
float intervalHO = circonf_cm / nb_aimants;            // Intervale entre 2 aimants en cm.

//-------------------------------------------------------------------------------------
// La constante suivante est à ajuster en fonction de la distance voulue pour le calcul du temps (UM)
//-------------------------------------------------------------------------------------
const int UM_DIST = 98;                 // distance de mesure en cm


volatile float distance = 0;                    // distance parcourue
volatile float dist_avg = 0;
volatile float dist_tot = 0;
volatile float dist_totHO = 0;
float conv_kmh = 3.6;                           // 3600 sec / 1000m

int afield;

unsigned long debounce_time, new_debounce_time;
unsigned long sensor_time_rise, sensor_time_fall;
unsigned long time_UM, time_UM_new;
volatile float dist_UM;
bool fg_speed_stable, fg_UM_cnt, fg_UM_cnt_end;

unsigned long LED_VERT_Blink = 0;

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);               // set the LCD address to 0x27 for a 16 chars and 2 line display



// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_VERT, OUTPUT);
  pinMode(LED_JAUNE, OUTPUT);

  digitalWrite(LED_BUILTIN, HIGH);

  delay(100);
  int tempo = 20;
 
  Serial.begin(115200);
  while (tempo > 0) {
      delay(100);
      tempo--;
      if(Serial) tempo = 0;
    ; // wait for serial port to connect. Needed for native USB
  }
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite(LED_JAUNE, LED_OFF);
  digitalWrite(LED_VERT, LED_OFF);
 
   // initialize digital pin SWitch as an input.
  pinMode(SW, INPUT_PULLUP);
 
  // initialize digital pin CAPTEUR_D7 as an output.
  pinMode(CAPTEUR_IN_D7, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(CAPTEUR_IN_D7), sens_change, CHANGE); 
   
   
//  pinMode(CAPTEUR_IN_A0, AnalogInput);    // NO need to define analog pins


  afield = analogRead(CAPTEUR_IN_A0);

  lcd.init();                      // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);                       // (x, y)
  lcd.print(" La Box a Laurent J ");
  lcd.setCursor(0, 2);                       // (x, y)
  lcd.print("Vers 1.5  18-02-2021");
  lcd.setCursor(0, 3);                       // (x, y)
  lcd.print("  Circonf. 18.47cm  ");

  Serial.println(" La Box a Laurent J ");
  Serial.println("Vers 1.5  18-02-2021");

  delay(5000);

  ref_time = 0;
  distance = 0;
  dist_avg = 0;
  pulse_cnt = 0;
  ref_time_avg = 0;

  sw_status = COUNT;
  sw_state = 1;

  serial_speed_avg = 0;
  speed_avg_delta_pos = 1;
  speed_avg_delta_neg = 1;

  time_UM = 0;
  dist_UM = 0;
  fg_speed_stable = FALSE;
  fg_UM_cnt = FALSE;
  fg_UM_cnt_end = FALSE;
}

// the loop function runs over and over again forever
void loop() {
   if(sense > 0)
    {
    //digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)

    //new_time = millis();

    if(ref_time != 0)
      {
      delta_t = new_time - ref_time;
      speed_i = (3600 * sense * interval) / delta_t;       // vitesse instantanée en m/s
      }
   
    ref_time = new_time;

    sense = 0;

    if(ref_time_avg != 0)
        {
        speed_avg = (3600 * dist_avg)/(new_time - ref_time_avg);           // 3.6 = (3600 sec/h * 1000 ms/sec) / 1000m/km
        dist_avg = 0;                       // PA v10
        ref_time_avg = new_time;            // PA v10

        if (speed_avg != 0)
            {
            serial_speed_avg = (serial_speed_avg * 7) + speed_avg;        // PA V11: moyenne sur 8 echantillons
            serial_speed_avg = serial_speed_avg / 8;

            speed_avg_delta = speed_avg - serial_speed_avg;               // v11: calculate positiv and negativ delta
            if (speed_avg_delta < 0)
                {
                speed_avg_delta_neg = -speed_avg_delta;
                speed_avg_delta_neg = speed_avg_delta_neg / serial_speed_avg;     
                }
            else
                {
                speed_avg_delta_pos = speed_avg_delta;
                speed_avg_delta_pos = speed_avg_delta_pos / serial_speed_avg;
                }

            }
        else
            {
            serial_speed_avg = 0;

            speed_avg_delta_pos = 1;
            speed_avg_delta_neg = 1;
            }
        }
    else
        {
        ref_time_avg = new_time;
        }
    }

  lcd_new_time = millis();
  serial_new_time = lcd_new_time;        // v12

  if((lcd_new_time - lcd_time) > 1000)
    {

// PA 
    lcd.setCursor(0, 0);
    if(fg_UM_cnt_end == TRUE)
        lcd.print("Pls:      Temp:     ");
    else
        lcd.print("Pls:                ");
       
    lcd.setCursor(0, 1);
    lcd.print("Dist.en  m:         ");
    lcd.setCursor(0, 2);
    lcd.print("Dist.en km:         ");
    lcd.setCursor(0, 3);
    lcd.print("Vit.moy.:       km/h");

           
    lcd.setCursor(5, 0);
    lcd.print(pulse_cnt_tot);
     
    lcd.setCursor(15, 0);
    lcd.print((float)time_UM/1000);
     
    lcd.setCursor(13, 1);
    lcd.print(dist_totHO/100);
     
    lcd.setCursor(13, 2);
    lcd.print(dist_tot/1000);
     
    lcd.setCursor(10, 3);
    lcd.print(speed_avg);
     
 #ifdef DEBUG   
     Serial.print("pulse_cnt: ");
     Serial.print(pulse_cnt_tot);
     Serial.print("   - distance_avg (m): ");
     Serial.print(dist_avg);
     Serial.print("   - speed_avg (km/h): ");
#endif

// ------------- v11 --------------------------------
     if(serial_speed_avg != 0)
        {
        if((serial_new_time - serial_time) > MIN_SERIAL_TEMPO)
            {
/*            speed_avg_delta = speed_avg - serial_speed_avg;
            if (speed_avg_delta < 0)
                {
                speed_avg_delta_neg = -speed_avg_delta;
                speed_avg_delta_neg = speed_avg_delta_neg / serial_speed_avg;     
                }
            else
                {
                speed_avg_delta_pos = speed_avg_delta;
                speed_avg_delta_pos = speed_avg_delta_pos / serial_speed_avg;
                }
*/
            if((speed_avg_delta_pos < MAX_SPEED_ERR)  && (speed_avg_delta_neg < MAX_SPEED_ERR))
                {
                digitalWrite(LED_VERT, LED_ON);
                LED_VERT_Blink = 10;
                Serial.println(serial_speed_avg);                     // envoi serie pour TC
               
                serial_time = serial_new_time;
                   
                speed_avg_delta_pos = 1;
                speed_avg_delta_neg = 1;

                fg_speed_stable = TRUE;
                }
            else if ( LED_VERT_Blink > 0)
                {
                LED_VERT_Blink--;
                if (LED_VERT_Blink == 0)
                    {
                    digitalWrite(LED_VERT, LED_ON);
                    }
                else if (LED_VERT_Blink == 7)
                    {
                    digitalWrite(LED_VERT, LED_OFF);
                    }
                }
            else
                {
                digitalWrite(LED_VERT, LED_OFF);
                fg_speed_stable = FALSE;   
                }
            }
        }
     else
        {
        serial_time = serial_new_time;
        }
//------------------ v11 end -----------------------
     
     if (sw_status == COUNT)
        {
        speed_avg = 0;                                 // PA v10 à VERIFIER !!!! le 25-12-2020 
        }
     
     lcd_time = lcd_new_time;
     //ref_time_avg = 0;
     //dist_avg = 0;        // PA v10
     pulse_cnt = 0;
    }

if((digitalRead(SW) == 0) && (sw_state == 0))
    {
     sw_state = 1000;                // debounce
     if(sw_status == END_FREEZ)         // FREEZ --> CLEAR
        {
        sw_status = CLEAR;
        digitalWrite(LED_VERT, LED_ON);   
        digitalWrite(LED_JAUNE, LED_OFF);     
       
        dist_tot = 0; 
        dist_totHO = 0;
        pulse_cnt_tot = 0;
        speed_avg = 0;

        fg_speed_stable = FALSE;
        time_UM = 0;
        fg_UM_cnt = FALSE;
        fg_UM_cnt = FALSE;
        fg_UM_cnt_end = FALSE;
        }
     else if (sw_status == COUNT)
        {
        sw_status = FREEZ;   
        digitalWrite(LED_JAUNE, LED_ON);
        }
     }

else if(digitalRead(SW) == 1)
    {
    if (sw_state > 0)sw_state--;      // debounce
   
    else if(sw_status == CLEAR)         // CLEAR --> COUNT
        {
        sw_status = COUNT;
        digitalWrite(LED_VERT, LED_OFF);
        }
     else if (sw_status == FREEZ)
        {
        sw_status = END_FREEZ;
        //digitalWrite(LED_JAUNE, LED_OFF); 
        }
    }
}


void sens_change() {
  delayMicroseconds(100);      // debounce delay 10µs
  if(digitalRead(CAPTEUR_IN_D7) == 1)
    {
    sensor_time_rise = micros();
    if((sensor_time_rise - sensor_time_fall) > 2000) {        // if delay > 10ms
        if((sensor_state == SENSOR_OFF) && (sw_status == COUNT))
            {
            new_time = millis();
           
            sense++;
            pulse_cnt++;
            pulse_cnt_tot++;
            distance += interval;
            dist_avg += interval;
            dist_tot += interval;
            dist_totHO += intervalHO;
            sensor_state = SENSOR_ON;
            digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)

            if(fg_speed_stable == TRUE)
                {
                if(fg_UM_cnt == FALSE)
                    {
                    time_UM_new = new_time;
                    fg_UM_cnt = TRUE;
                    fg_UM_cnt_end = FALSE;
                    dist_UM = 0;
                    digitalWrite(LED_VERT, LOW);
                    }
                else if (dist_UM < UM_DIST)               // en cm
                    {
                    time_UM = new_time - time_UM_new;   
                    dist_UM += intervalHO;
                    }
                else
                    {
                    digitalWrite(LED_VERT, HIGH); 
                    fg_UM_cnt_end = TRUE; 
                    }
                }
            else
                {
                dist_UM = 0;
                //time_UM = 0;
                fg_UM_cnt = FALSE;
                if(fg_UM_cnt_end != TRUE)
                    {
                    dist_UM = 0;
                    time_UM = 0;
                    }
               
                //digitalWrite(LED_VERT, LOW);
                }
            }
        }
    }

  else                                        //    if(digitalRead(CAPTEUR_IN_D7) == 0)
    {
    if(sensor_state == SENSOR_ON)
        {
        sensor_time_fall = micros();
        if((sensor_time_fall - sensor_time_rise) > 2000) {        // if delay > 10ms
            sensor_state = SENSOR_OFF;
             digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
            }
        }
    }

}

Bonne journée ;)