Ceci est une ancienne révision du document !
Table des matières
Vélos interactifs
Installation du driver FTDI
Tous les boîtiers ENTTEC utilisent une puce FTDI pour la communications à travers le port USB. Voici la procédure pour l'installer sur une RPI4 :
wget https://ftdichip.com/wp-content/uploads/2022/07/libftd2xx-arm-v8-1.4.27.tgz tar -xvf libftd2xx-arm-v8-1.4.27.tgz sudo cp release/build/lib* /usr/local/lib cd /usr/local/lib ls sudo ln -s libftd2xx.so.1.4.27 libftd2xx.so sudo chmod 0755 libftd2xx.so.1.4.27
Brancher le boîtier ENTTEC
sudo rmmod ftdi_sio sudo rmmod usbserial cd cd release/examples make cd EEPROM/read ls sudo ./read
Installation du addon ofxGenericDmx
Installation de la librairie ftdi :
sudo apt-get install libftdi-dev
Pour certaines distributions, il pourrait être nécessaire d'autoriser l'utilisateur à accéder à l'interface via son port USB. Des solutions diverses sont détaillées ici
wget https://github.com/woutgg/ofxGenericDmx/archive/refs/heads/master.zip cd openFrameworks/addons/ofxGenericDmx/ofxGenericDmx_EnttecDmxUsbProExample make startx ./bin/ofxGenericDmx_EnttecDmxUsbProExample -- -s off
Si vous souhaitez partir d'un projet vierge, il faudra ajouter des instructions pour le linker lors de la compilation : Dans le fichier config.make du projet :
sudo nano config.make
Vérifiez les lignes suivantes :
PROJECT_LDFLAGS=-Wl,-rpath=./libs PROJECT_LDFLAGS+=-lftdi
Code
// g++ -Wall -o compteur compteur.c -l wiringPi // ./compteur #include <wiringPi.h> #include <stdio.h> #include <stdlib.h> #define COMPTEUR 26 #define TEMOIN 19 int drapeau = 0; int main() { wiringPiSetupGpio(); pinMode (COMPTEUR, INPUT); pullUpDnControl(COMPTEUR, PUD_UP); pinMode (TEMOIN, OUTPUT); digitalWrite(TEMOIN, LOW); while(1) { if ((digitalRead(COMPTEUR) == LOW) && (drapeau == 0)) { digitalWrite(TEMOIN, HIGH); delay(20); drapeau = 1; } if (digitalRead(COMPTEUR) == HIGH) { drapeau = 0; } } return 0; }
ofApp.h
#pragma once #include "ofMain.h" #include "ofxGenericDmx.h" #include "ofUtils.h" #include <wiringPi.h> #include "Compteur.hpp" #define DMX_DATA_LENGTH 513 #define TEMOIN1 19 #define TEMOIN2 27 #define ROUE 2.27 class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); //pointer to our Enntec DMX USB Pro object DmxDevice* dmxInterface_; //our DMX packet (which holds the channel values + 1st byte for the start code) unsigned char dmxData_[DMX_DATA_LENGTH]; // Compteurs Compteur compteur1; Compteur compteur2; ofTrueTypeFont myfont; };
ofApp.cpp
#include <stdlib.h> #include "ofApp.h" //-------------------------------------------------------------- void ofApp::setup(){ ofSetFrameRate( 44 ); //zero our DMX value array memset( dmxData_, 0, DMX_DATA_LENGTH ); //open the device dmxInterface_ = ofxGenericDmx::openFirstDevice(); if ( dmxInterface_ == 0 ) printf( "No Enttec Device Found\n" ); else printf( "isOpen: %i\n", dmxInterface_->isOpen() ); //frames = 0; printf("ofxGenericDmx addon version: %s.%s\n", ofxGenericDmx::VERSION_MAJOR, ofxGenericDmx::VERSION_MINOR); // Initialisation valeurs compteur1.set(TEMOIN1, ROUE, ofGetCurrentTime().getAsMilliseconds()); compteur2.set(TEMOIN2, ROUE, ofGetCurrentTime().getAsMilliseconds()); // Affichage myfont.load("arial.ttf", 32); // WiringPi wiringPiSetupGpio(); } //-------------------------------------------------------------- void ofApp::update(){ dmxData_[401] = 80; dmxData_[402] = 160; dmxData_[403] = 255; //force first byte to zero (it is not a channel but DMX type info - start code) dmxData_[0] = 0; if ( ! dmxInterface_ || ! dmxInterface_->isOpen() ) { printf( "Not updating, enttec device is not open.\n"); } else{ //send the data to the dmx interface dmxInterface_->writeDmx( dmxData_, DMX_DATA_LENGTH ); } compteur1.mettreAJour(); compteur2.mettreAJour(); } //-------------------------------------------------------------- void ofApp::draw(){ ofBackground(0x21, 0X80, 0XC3); compteur1.afficher(0, 0, myfont); compteur2.afficher(640, 0, myfont); }
Compteur.hpp
#include "ofUtils.h" #include "ofGraphics.h" #include "ofTrueTypeFont.h" #include <wiringPi.h> class Compteur { public: // Constructeur Compteur(); void set(uint8_t _pinTemoin, float _roue, uint64_t _tempsDepart); //Accesseurs et mutateurs //void setX(int x); //void setY(int y); //int getX() const; //int getY() const; // Autres méthodes void afficher(int x, int y, ofTrueTypeFont police); void mettreAJour(); private: int x, y; int pinTemoin; float roue; int compteur; uint64_t temps, tempsDepart; uint16_t distance; float vitesseIntantanee; float vitesseMax; ofTrueTypeFont policeVitesse, policeDistance, policeLabel; };
Compteur.cpp
#include "Compteur.hpp" //-------------------------------------------------------------- Compteur::Compteur() { compteur = 0; temps = 0; vitesseIntantanee = 0.0; vitesseMax = 0.0; policeVitesse.load("AUDIMRG_.TTF", 12); policeDistance.load("arial.ttf", 50); policeLabel.load("arial.ttf", 20); distance = 0; } //-------------------------------------------------------------- void Compteur::afficher(int x, int y, ofTrueTypeFont police) { ofPushMatrix(); ofTranslate(x, y); ofSetCircleResolution(100); ofSetLineWidth(3); // Dessin du compteur ofPushMatrix(); ofTranslate(150, 800); // Aiguille de la vitesse Max ofSetColor(255, 0, 0); ofFill(); ofPushMatrix(); ofRotateDeg(60 + vitesseMax * 4); ofDrawTriangle(-6, 0, 0, 90, 6, 0); ofPopMatrix(); // Aiguille de la vitesse instantanée ofSetColor(0, 0, 0); ofPushMatrix(); ofRotateDeg(60 + vitesseIntantanee * 4); ofDrawTriangle(-6, 0, 0, 90, 6, 0); ofPopMatrix(); // Dessin du cadran ofSetColor(255, 255, 255); ofFill(); ofDrawCircle(0,0,20); ofSetColor(0,0,0); ofNoFill(); ofDrawCircle(0,0,100); ofDrawCircle(0,0,20); char nombre[3]; for (int i = 0; i < 61; i += 5) { ofPushMatrix(); ofRotateDeg(4 * i - 120); sprintf(nombre, "%i", i); policeVitesse.drawString(nombre, -policeVitesse.stringWidth(nombre) / 2, -115); ofDrawLine(0, -100, 0, -110); ofPopMatrix(); } ofSetColor(0, 0, 0); char labelCompteur[255]; sprintf(labelCompteur, "Vitesse max."); policeLabel.drawString(labelCompteur, -policeLabel.stringWidth(labelCompteur) / 2, 130); ofPopMatrix(); // Affichage de la distance ofPushMatrix(); ofTranslate(320, 750); ofSetColor(0, 0, 0); ofFill(); ofDrawRectangle(00, 00, 300, 100); ofSetColor(255, 255, 255); char ligneDistance[255]; sprintf(ligneDistance, "%i m", distance); policeDistance.drawString(ligneDistance, 290 - policeDistance.stringWidth(ligneDistance), 75); ofSetColor(0, 0, 0); char labelDistance[255]; sprintf(labelDistance, "Distance parcourue"); policeLabel.drawString(labelDistance, 20, 180); ofPopMatrix(); ofPopMatrix(); } //-------------------------------------------------------------- void Compteur::mettreAJour() { if (digitalRead(pinTemoin) == 1) { digitalWrite(pinTemoin, 0); compteur++; uint64_t tempsCourant = ofGetCurrentTime().getAsMilliseconds(); vitesseIntantanee = (3.6 * 1000 * roue) / (tempsCourant - temps); if (vitesseMax < vitesseIntantanee) { vitesseMax = vitesseIntantanee; } temps = tempsCourant; } // Mise à zéro de la vitesse si la roue est arrêtée if ((ofGetCurrentTime().getAsMilliseconds() - temps) > 6000) { vitesseIntantanee = 0; } distance = (int)(roue * compteur); } //-------------------------------------------------------------- void Compteur::set(uint8_t _pinTemoin, float _roue, uint64_t _tempsDepart) { pinTemoin = _pinTemoin; roue = _roue; tempsDepart = _tempsDepart; }
Démarrage automatique
sudo nano /etc/systemd/system/compteur.service
[Unit] Description=Met en route le compteur des vélos [Service] Type=simple WorkingDirectory=/home/pi/openFrameworks/apps/myApps/velosInteractifs/ ExecStart=/home/pi/openFrameworks/apps/myApps/velosInteractifs/./compteur Restart=on-failure RestartSec=1 User=pi Group=pi [Install] WantedBy=multi-user.target
sudo systemctl enable compteur.service
sudo systemctl status compteur.service
Construction d'un autre service pour la course :
sudo nano /etc/rc.local
Ajouter avant la ligne exit 0
startx ./home/pi/openFrameworks/apps/myApps/velosInteractifs/bin/velosInteractifs -- -s off &
Il faut aussi désactiver les sorties audio par l'HDMI. Ajouter ,noaudio à la fin de la ligne dtoverlay=vc4-kms-v3d dans le fichier /boot/firmware/config.txt :
sudo nano /boot/firmware/config.txt dtoverlay=vc4-kms-v3d,noaudio
