1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-12-22 05:30:37 +01:00
This commit is contained in:
Geoffrey Frogeye 2018-04-30 16:15:47 +02:00
parent 13d188e6f4
commit 553c550ac7
17 changed files with 618 additions and 109 deletions

View file

@ -13,3 +13,9 @@ Ce document a pour but de recenser les connexions entre les différents composan
## Connexions de puissance
## Connexions d'information
- BCM 2 (SDA), BCM 3 (SCL) : liaison I2C (LCD, IMU, SRF08)
- BCM 14 (TXD), BCM 15 (RXD) : liaison série (PC debug)
- BCM 12 (PWM0), BCM 13 (PWM1) : contrôleur moteur
- BCM 17, BCM 27 : bouton rouge, bouton jaune
- BCM 22 : tirette

2
chef/lcdOff.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
/usr/sbin/i2cset -y 1 0x27 0x00

View file

@ -1,5 +1,6 @@
#!/bin/sh
cd "$( dirname "${BASH_SOURCE[0]}" )"
EXEC=bin/premier
LOGFILE="${2:=run.log}"
@ -7,3 +8,5 @@ LOGFILE="${2:=run.log}"
"$EXEC" 2>&1 | while read line; do
echo "$(cat /proc/uptime | cut -d ' ' -f 1) $line" >> "$LOGFILE"
done
sh lcdOff.sh

301
chef/src/ihm.c Normal file
View file

@ -0,0 +1,301 @@
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>
#include <wiringPi.h>
#include "ihm.h"
#include "movement.h"
#include "parcours.h"
#include "points.h"
// Globales
pthread_t tIHM;
// Fonctions
void configureIHM()
{
initLCD();
gotoLCD(LCD_LINE_1);
printLCD("Demarrage...");
}
void startIHM()
{
pinMode(IHM_PIN_ROUGE, INPUT);
pullUpDnControl(IHM_PIN_ROUGE, PUD_UP);
pinMode(IHM_PIN_JAUNE, INPUT);
pullUpDnControl(IHM_PIN_JAUNE, PUD_UP);
pinMode(IHM_PIN_TIRETTE, INPUT);
pullUpDnControl(IHM_PIN_TIRETTE, PUD_UP);
pthread_create(&tIHM, NULL, TaskIHM, NULL);
pthread_join(tIHM, NULL);
}
// t1 - t2
void diffTimespec(const struct timespec* t1, const struct timespec* t2, struct timespec* td)
{
if ((t1->tv_nsec - t2->tv_nsec) < 0) {
td->tv_sec = t1->tv_sec - t2->tv_sec - 1;
td->tv_nsec = t1->tv_nsec - t2->tv_nsec + 1000000000UL;
} else {
td->tv_sec = t1->tv_sec - t2->tv_sec;
td->tv_nsec = t1->tv_nsec - t2->tv_nsec;
}
}
bool debunkButtonIHM(int pin)
{
int t;
// Press (cancel if wrong)
for (t = IHM_DEBUNK_TIME / 2; t > 0; t--) {
if (digitalRead(pin) != LOW) {
return false;
}
delay(1);
}
// Release (re-wait if wrong)
for (t = IHM_DEBUNK_TIME / 2; t > 0; t--) {
if (digitalRead(pin) != HIGH) {
t = IHM_DEBUNK_TIME / 2;
}
delay(1);
}
return true;
}
enum boutons pressedIHM(int timeout)
{
bool block = timeout < 0;
while (timeout > 0 || block) {
if (debunkButtonIHM(IHM_PIN_JAUNE)) {
return jaune;
}
if (debunkButtonIHM(IHM_PIN_ROUGE)) {
return rouge;
}
delay(IHM_POLLING_INTERVAL);
timeout -= IHM_POLLING_INTERVAL;
}
return none;
}
bool tirettePresente()
{
int etat, newEtat;
int t;
for (t = 0; t < IHM_DEBUNK_TIME; t++) {
newEtat = digitalRead(IHM_PIN_TIRETTE);
if (etat != newEtat) {
t = 0;
etat = newEtat;
}
delay(1);
}
return etat == LOW;
}
char tempLine[16];
bool isDebug = false;
bool isOrange = true;
bool annuler = false;
clock_t lastCalibrage = 0;
clock_t parcoursStart = 0;
pthread_t tParcours;
void printCouleur()
{
if (isOrange) {
printLCD("Orange");
} else {
printLCD("Vert");
}
}
void* TaskIHM(void* pdata)
{
(void)pdata;
gotoLCD(LCD_LINE_1 + 1);
printLCD("Niuh");
enum boutons bout;
for (;;) {
// Debug
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Debug : ");
if (isDebug) {
printLCD("On");
gotoLCD(LCD_LINE_2);
printLCD("192.168.0.0 TODO");
} else {
printLCD("Off");
}
bout = pressedIHM(IHM_REFRESH_INTERVAL);
if (bout == rouge) {
isDebug = !isDebug;
} else if (bout == jaune) {
break;
}
}
// Couleur
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Couleur : ");
printCouleur();
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
isOrange = !isOrange;
} else if (bout == jaune) {
break;
}
}
// Calibrage
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
if (lastCalibrage != 0) {
printLCD("Calibre il y a");
gotoLCD(LCD_LINE_2);
sprintf(tempLine, "%ld secondes", (clock() - lastCalibrage) / CLOCKS_PER_SEC);
printLCD(tempLine);
} else {
printLCD("Calibrer");
gotoLCD(LCD_LINE_2);
printLCD("(");
printCouleur();
printLCD(")");
}
bout = pressedIHM(IHM_REFRESH_INTERVAL);
if (bout == rouge) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Calibrage...");
delay(3000); // TODO
lastCalibrage = clock();
} else if (bout == jaune) {
break;
}
}
// Diagnostics
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Diagnostiquer");
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Diagnostics...");
delay(3000); // TODO
} else if (bout == jaune) {
break;
}
}
// Parcours
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Lancer parcours");
gotoLCD(LCD_LINE_2);
printLCD("(");
printCouleur();
printLCD(")");
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
// No tirette
annuler = false;
while (!tirettePresente()) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Inserez tirette");
gotoLCD(LCD_LINE_2);
printLCD("(ROUGE: ignorer)");
bout = pressedIHM(IHM_REFRESH_INTERVAL);
if (bout == rouge) {
break;
} else if (bout == jaune) {
annuler = true;
break;
}
}
if (annuler) {
continue;
}
// Go!
prepareParcours(isOrange);
while (tirettePresente()) {
bout = pressedIHM(IHM_POLLING_INTERVAL);
if (bout == jaune) {
annuler = true;
break;
}
}
if (annuler) {
continue;
}
startParcours(); // TODO On a different thread
int toWait;
while ((toWait = updateParcours()) >= 0) {
if (pressedIHM(toWait) != none) {
break;
}
}
stopParcours();
pressedIHM(IHM_BLOCK); // Nécessite 3 appuis pour éviter d'enlever le score par inadvertance
pressedIHM(IHM_BLOCK);
pressedIHM(IHM_BLOCK);
} else if (bout == jaune) {
break;
}
}
// RàZ
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Remettre a zero");
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Remise a zero...");
delay(3000); // TODO
} else if (bout == jaune) {
break;
}
}
}
}
void deconfigureIHM()
{
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Bye bye!");
}

27
chef/src/ihm.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef __IHM_H_
#define __IHM_H_
#include "lcd.h"
#define IHM_PIN_ROUGE 0
#define IHM_PIN_JAUNE 2
#define IHM_PIN_TIRETTE 3
// ms
#define IHM_BLOCK -1
#define IHM_POLLING_INTERVAL 50
#define IHM_DEBUNK_TIME 50
#define IHM_REFRESH_INTERVAL 1000
enum boutons {none, jaune, rouge};
// Public
void configureIHM();
void startIHM();
void deconfigureIHM();
// Private
void* TaskIHM(void *pdata);
enum boutons pressedIHM(int timeout); // timeout: ms or -1
#endif

View file

@ -1,9 +1,11 @@
#include "lcd.h"
#include "i2c.h"
#include <pthread.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include "lcd.h"
int lcdFd;
pthread_mutex_t sLCD;
void initLCD()
{
@ -43,7 +45,6 @@ void printLCD(char* s)
}
}
void sendLCD(uint8_t bits, uint8_t mode)
{
lockI2C();
@ -66,3 +67,13 @@ void toggleEnableLCD(uint8_t bits)
wiringPiI2CReadReg8(lcdFd, (bits & ~LCD_MASK_ENABLE));
delayMicroseconds(50);
}
void lockLCD()
{
pthread_mutex_lock(&sLCD);
}
void unlockLCD()
{
pthread_mutex_unlock(&sLCD);
}

View file

@ -2,6 +2,7 @@
#define __LCD_H_
#include "stdint.h"
#include "i2c.h"
#define LCD_ADDR 0x27
@ -23,6 +24,9 @@ void clearLCD();
void gotoLCD(uint8_t line);
void charLCD(char c);
void printLCD(char* s);
// Not necessary, but should be used when different threads use the display
void lockLCD();
void unlockLCD();
// Private
void sendLCD(uint8_t bits, uint8_t mode);

View file

@ -1,36 +1,36 @@
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h> // sleep
#include "debug.h"
#define TEMPS_PARCOURS 10
unsigned long int canard = 42;
double banane = 63;
char* artichaut = "Torticoli";
// t1 - t2
void diffTimespec(const struct timespec* t1, const struct timespec* t2, struct timespec* td)
{
if ((t1->tv_nsec - t2->tv_nsec) < 0) {
td->tv_sec = t1->tv_sec - t2->tv_sec - 1;
td->tv_nsec = t1->tv_nsec - t2->tv_nsec + 1000000000UL;
} else {
td->tv_sec = t1->tv_sec - t2->tv_sec;
td->tv_nsec = t1->tv_nsec - t2->tv_nsec;
}
}
int main()
{
struct timespec start, now, diff;
clock_gettime(CLOCK_REALTIME, &start);
printf("Démarrage...\n");
srand(time(NULL));
configureDebug();
registerDebugVar("canard", ld, &canard);
registerDebugVar("banane", lf, &banane);
registerDebugVar("artichaut", s, &artichaut);
startDebug();
for (int i = 0; i < 2; i++) {
printf("21 %d\n", i);
canard += 3;
banane /= 2;
sleep(1);
for (;;) {
clock_gettime(CLOCK_REALTIME, &now);
diffTimespec(&now, &start, &diff);
if (diff.tv_sec > TEMPS_PARCOURS) {
break;
}
printf("32 %ld %ld\n", diff.tv_sec, diff.tv_nsec);
}
deconfigureDebug();
return EXIT_SUCCESS;
}

View file

@ -6,10 +6,6 @@
void configureMovement()
{
if (wiringPiSetup() == -1) {
fprintf(stderr, "Impossible d'initialiser WiringPi\n");
exit(EXIT_FAILURE);
}
pinMode(ENA, PWM_OUTPUT);
pinMode(ENB, PWM_OUTPUT);
}
@ -90,3 +86,9 @@ void deconfigureMovement()
{
}
int stop()
{
brake();
// TODO
}

View file

@ -8,19 +8,31 @@
#include "position.h"
#include <wiringPi.h>
#define PWM_MAX 1023
#define PWM_MAX_V 3.3
// #define TESTINATOR
#define TLE5206
#ifdef TESTINATOR
#define MOT_MIN_V 0.1
#define MOT_MAX_V 2.0
#endif
#ifdef TLE5206
#define MOT_MIN_V 0.1
#define MOT_MAX_V 2.5
#endif
// Pins definition
// Left
// Physical 32
#define ENA 26
#define IN1 2
#define IN2 3
// Physical 33
// Right
#define ENB 23
#define IN3 4
#define IN4 5

137
chef/src/parcours.c Normal file
View file

@ -0,0 +1,137 @@
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include "parcours.h"
#include "movement.h"
#include "position.h"
#include "points.h"
#include "lcd.h"
pthread_t tParcours;
bool isOrange;
char tempLine[16];
struct timespec tempsStart;
struct timespec tempsNow;
struct timespec tempsEcoule;
void prepareParcours(bool orange)
{
isOrange = orange;
clearLCD();
gotoLCD(LCD_LINE_1);
sprintf(tempLine, "--:--/%2d:%02d", TEMPS_PARCOURS / 60, TEMPS_PARCOURS % 60);
printLCD(tempLine);
gotoLCD(LCD_LINE_1 + 16 - 3);
printLCD("ATT");
resetPoints();
showPoints();
gotoLCD(LCD_LINE_2 + 16 - 3);
printLCD(isOrange ? "Org" : "Vrt");
}
void startParcours()
{
clock_gettime(CLOCK_REALTIME, &tempsStart);
pthread_create(&tParcours, NULL, TaskParcours, NULL); // TODO Start on mutex unlock
lockLCD();
gotoLCD(LCD_LINE_1 + 16 - 3);
printLCD(" ");
unlockLCD();
}
void updateTimeDisplay()
{
lockLCD();
gotoLCD(LCD_LINE_1);
sprintf(tempLine, "%2ld:%02ld", tempsEcoule.tv_sec / 60, tempsEcoule.tv_sec % 60);
printLCD(tempLine);
unlockLCD();
}
int updateParcours()
{
clock_gettime(CLOCK_REALTIME, &tempsNow);
if ((tempsNow.tv_nsec - tempsStart.tv_nsec) < 0) {
tempsEcoule.tv_sec = tempsNow.tv_sec - tempsStart.tv_sec - 1;
tempsEcoule.tv_nsec = tempsNow.tv_nsec - tempsStart.tv_nsec + 1000000000UL;
} else {
tempsEcoule.tv_sec = tempsNow.tv_sec - tempsStart.tv_sec;
tempsEcoule.tv_nsec = tempsNow.tv_nsec - tempsStart.tv_nsec;
}
if (tempsEcoule.tv_sec >= TEMPS_PARCOURS) {
return -1;
}
updateTimeDisplay();
return (1000000000UL - tempsEcoule.tv_nsec) / 1000000UL;
}
void stopParcours()
{
pthread_cancel(tParcours);
stop();
updateTimeDisplay();
gotoLCD(LCD_LINE_1 + 16 - 3);
printLCD("FIN");
showPoints();
}
void* TaskParcours(void* pdata)
{
(void)pdata;
for (;;) {
delay(250);
addPoints(1);
}
}
void* TaskParcours2(void* pdata)
{
(void)pdata;
/* struct position pos; */
/* for (;;) { */
/* pos.x = (int) (rand()*200.0/RAND_MAX); */
/* pos.y = (int) (rand()*100.0/RAND_MAX); */
/* pos.o = (int) (rand()*360.0/RAND_MAX); */
/* aller(&pos); */
/* sleep(1); */
/* brake(); */
/* sleep(2); */
/* } */
struct timespec tim; // 10 ms
tim.tv_sec = 0;
tim.tv_nsec = 10000000L;
#define RAMP_TIME 100
#define MAX_VIT MOT_MAX_V
/* for (;;) { */
// ↗
for (int i = 0; i < RAMP_TIME; i++) {
float p = (float)i / (float)RAMP_TIME;
changerMoteurs(p * MOT_MAX_V, p * MOT_MAX_V);
nanosleep(&tim, NULL);
}
changerMoteurs(MOT_MAX_V, MOT_MAX_V);
// ↑
sleep(2);
/* // ↘ */
/* for (int i = 0; i < RAMP_TIME; i++) { */
/* float p = (float) i / (float) RAMP_TIME; */
/* p = 1 - p; */
/* changerMoteurs(p * MOT_MAX_V, p * MOT_MAX_V); */
/* nanosleep(&tim, NULL); */
/* } */
/* sleep(5); */
/* } */
return NULL;
}

15
chef/src/parcours.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef __PARCOURS_H__
#define __PARCOURS_H__
#include <stdbool.h>
#define TEMPS_PARCOURS 100
void prepareParcours(bool orange);
void startParcours();
// Returns : -1 if parcours ended, N ms for the next time it should be checked
int updateParcours();
void stopParcours();
void* TaskParcours(void* pdata);
#endif

31
chef/src/points.c Normal file
View file

@ -0,0 +1,31 @@
#include <stdio.h>
#include "lcd.h"
int points;
char tempLine[16];
void resetPoints()
{
points = 0;
}
int getPoints()
{
return points;
}
void showPoints()
{
sprintf(tempLine, "%d points", getPoints());
lockLCD();
gotoLCD(LCD_LINE_2);
printLCD(tempLine);
unlockLCD();
}
void addPoints(int pts)
{
points += pts;
showPoints();
}

10
chef/src/points.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef __POINTS_H__
#define __POINTS_H__
// Public
void resetPoints();
int getPoints();
void addPoints(int points);
void showPoints();
#endif

View file

@ -1,93 +1,40 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h> // random seed
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // random seed
#include <unistd.h> // sleep
#include <wiringPi.h>
#include "CF.h"
#include "debug.h"
#include "ihm.h"
#include "movement.h"
#include "position.h"
#include "debug.h"
#define TEMPSMAX 60
void* TaskParcours(void *pdata)
{
(void) pdata;
/* struct position pos; */
/* for (;;) { */
/* pos.x = (int) (rand()*200.0/RAND_MAX); */
/* pos.y = (int) (rand()*100.0/RAND_MAX); */
/* pos.o = (int) (rand()*360.0/RAND_MAX); */
/* aller(&pos); */
/* sleep(1); */
/* brake(); */
/* sleep(2); */
/* } */
struct timespec tim; // 10 ms
tim.tv_sec = 0;
tim.tv_nsec = 10000000L;
#define RAMP_TIME 100
#define MAX_VIT MOT_MAX_V
/* for (;;) { */
// ↗
for (int i = 0; i < RAMP_TIME; i++) {
float p = (float) i / (float) RAMP_TIME;
changerMoteurs(p * MOT_MAX_V, p * MOT_MAX_V);
nanosleep(&tim, NULL);
}
changerMoteurs(MOT_MAX_V, MOT_MAX_V);
// ↑
sleep(2);
/* // ↘ */
/* for (int i = 0; i < RAMP_TIME; i++) { */
/* float p = (float) i / (float) RAMP_TIME; */
/* p = 1 - p; */
/* changerMoteurs(p * MOT_MAX_V, p * MOT_MAX_V); */
/* nanosleep(&tim, NULL); */
/* } */
/* sleep(5); */
/* } */
printf("Fin du parcours\n");
return NULL;
}
int main()
{
printf("Démarrage...\n");
configureDebug();
configureCF();
configureMovement();
configurePosition();
startDebug();
srand(time(NULL));
/* printf("En attente de la tirette...\n"); // TODO */
printf("C'est parti !\n");
pthread_t tParcours;
pthread_create(&tParcours, NULL, TaskParcours, NULL);
sleep(TEMPSMAX);
printf("Fin des %d secondes\n", TEMPSMAX);
/* pthread_cancel(tParcours); */
for (;;) {
if (wiringPiSetup() < 0) {
fprintf(stderr, "Impossible d'initialiser WiringPi\n");
exit(EXIT_FAILURE);
}
initI2C();
configureIHM();
/* stop(); */
srand(time(NULL));
configureDebug();
/* configureCF(); */
/* configureMovement(); */
/* configurePosition(); */
startDebug();
deconfigureMovement();
deconfigurePosition();
deconfigureCF();
startIHM();
/* deconfigureMovement(); */
/* deconfigurePosition(); */
/* deconfigureCF(); */
deconfigureIHM();
deconfigureDebug();
return EXIT_SUCCESS;
}

View file

@ -8,6 +8,7 @@ start() {
modprobe pl2303 # USB↔Serial cable
modprobe i2c-bcm2708 # I2C
modprobe i2c-dev # I2C
/opt/chef/i2cOff.sh
echo "OK"
}

View file

@ -18,7 +18,7 @@ define CHEF_INSTALL_TARGET_CMDS
$(INSTALL) -d -m 0755 $(TARGET_DIR)/opt/chef/com
$(INSTALL) -d -m 0755 $(TARGET_DIR)/opt/chef/log
$(INSTALL) -D -m 0755 $(@D)/bin/* $(TARGET_DIR)/opt/chef/bin
$(INSTALL) -D -m 0755 $(@D)/run.sh $(TARGET_DIR)/opt/chef
$(INSTALL) -D -m 0755 $(@D)/*.sh $(TARGET_DIR)/opt/chef
endef
$(eval $(generic-package))