Outils pour utilisateurs

Outils du site


projet_europ

Ceci est une ancienne révision du document !


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
projet_europ.1734186955.txt.gz · Dernière modification : de Mushussu