1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-11-24 09:06:03 +01:00

Better IHM

This commit is contained in:
Geoffrey Frogeye 2018-04-30 22:40:20 +02:00
parent 553c550ac7
commit 760b950e83
17 changed files with 244 additions and 211 deletions

View file

@ -10,6 +10,9 @@ LDFLAGS_CUSTOM += -lpthread -lwiringPi
CFLAGS_CUSTOM += -g
## Générateurs de drapeaux pour les bibliothèques
PKG_CONFIG=pkg-config
## Nom des objets communs
OBJS=CF debug i2c ihm lcd movement parcours points position
OBJS_O=$(addprefix obj/,$(addsuffix .o,$(OBJS)))
# VARIABLES AUTOMATIQUES
ifdef LIBS
@ -21,25 +24,20 @@ endif
CFLAGS += -Wall -Wextra -pedantic -g -DDEBUG
# buildroot se charge de remplacer ces flags avec des optimisations
# RÈGLES AUTOMATIQUES DE COMPILATION
# RÈGLES DE COMPILATION
# Règle éxecutée par défaut (quand on fait juste `make`)
default: bin/premier bin/local $(subst src,bin,$(subst .c,,$(wildcard src/test*.c)))
# Génération des fichiers éxecutables
bin/%: obj/%.o
bin/%: obj/%.o $(OBJS_O)
$(CC) $(LDFLAGS) $(LDFLAGS_CUSTOM) $^ -o $@
$(OBJCOPY) --only-keep-debug $@ $@.debug
$(STRIP) --strip-debug --strip-unneeded $@
# RÈGLES DE COMPILATION
# Règle éxecutée par défaut (quand on fait juste `make`)
default: bin/testpin bin/premier bin/local bin/testI2c
# Binaires (dont il faut spécifier les objets explicitement)
OBJS=CF movement debug position ihm lcd i2c points parcours
bin/premier: $(addprefix obj/,$(addsuffix .o,$(OBJS)))
bin/testPin: obj/testPin.o
# TODO ↑ Enlever (remplacé par IHM)
bin/testI2c: obj/testI2c.o obj/i2c.o obj/srf08.o obj/lcd.o
bin/premier: obj/premier.o $(OBJS_O)
bin/test%: obj/test%.o $(OBJS_O)
# Programme de test sur PC, n'embarquant pas wiringPi
bin/local: obj/local.o obj/debug.o

View file

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

View file

@ -114,7 +114,7 @@ void configureCF()
pthread_mutex_init(&sSendCF, NULL);
pthread_create(&tReaderAC, NULL, TaskReaderAC, NULL);
printf("Attente de réponse de l'Fpga... ");
printf("Attente de réponse du Fpga... ");
fflush(stdout);
struct timespec tim;
tim.tv_sec = 0;

View file

@ -20,7 +20,7 @@ void* TaskDebug(void* pdata)
(void)pdata;
clock_t debugStart;
debugStart = clock();
debugStart = clock(); // TODO struct timespec
struct timespec tim; // 100 ms
tim.tv_sec = 0;

View file

@ -1,6 +1,5 @@
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>
#include <wiringPi.h>
@ -12,13 +11,13 @@
// Globales
pthread_t tIHM;
pthread_t tStdinIHM;
// Fonctions
void configureIHM()
{
initLCD();
gotoLCD(LCD_LINE_1);
printLCD("Demarrage...");
printToLCD(LCD_LINE_1, "Demarrage");
}
void startIHM()
@ -31,6 +30,7 @@ void startIHM()
pullUpDnControl(IHM_PIN_TIRETTE, PUD_UP);
pthread_create(&tIHM, NULL, TaskIHM, NULL);
pthread_create(&tStdinIHM, NULL, TaskStdinIHM, NULL);
pthread_join(tIHM, NULL);
}
@ -66,11 +66,35 @@ bool debunkButtonIHM(int pin)
return true;
}
enum boutons stdinbutton = none;
void* TaskStdinIHM(void* pdata)
{
(void)pdata;
for (;;) {
char c = getchar();
if (c == '1') {
stdinbutton = jaune;
} else if (c == '2') {
stdinbutton = rouge;
}
}
return NULL;
}
enum boutons pressedIHM(int timeout)
{
bool block = timeout < 0;
while (timeout > 0 || block) {
if (stdinbutton != none) {
enum boutons bout = stdinbutton;
stdinbutton = none;
return bout;
}
if (debunkButtonIHM(IHM_PIN_JAUNE)) {
return jaune;
}
@ -100,44 +124,33 @@ bool tirettePresente()
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()
char* orangeStr = "Orange";
char* vertStr = "Vert";
char* getCouleur()
{
if (isOrange) {
printLCD("Orange");
} else {
printLCD("Vert");
}
return isOrange ? orangeStr : vertStr;
}
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 : ");
printfToLCD(LCD_LINE_1, "Debug : %s", isDebug ? "On" : "Off");
if (isDebug) {
printLCD("On");
gotoLCD(LCD_LINE_2);
printLCD("192.168.0.0 TODO");
} else {
printLCD("Off");
printToLCD(LCD_LINE_2, "192.168.0.0 TODO");
}
bout = pressedIHM(IHM_REFRESH_INTERVAL);
@ -151,9 +164,7 @@ void* TaskIHM(void* pdata)
// Couleur
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Couleur : ");
printCouleur();
printfToLCD(LCD_LINE_1, "Couleur : %s", getCouleur());
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
@ -166,27 +177,20 @@ void* TaskIHM(void* pdata)
// 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);
printToLCD(LCD_LINE_1, "Calibre il y a");
printfToLCD(LCD_LINE_2, "%ld secondes", (clock() - lastCalibrage) / CLOCKS_PER_SEC);
} else {
printLCD("Calibrer");
gotoLCD(LCD_LINE_2);
printLCD("(");
printCouleur();
printLCD(")");
printToLCD(LCD_LINE_1, "Calibrer");
printfToLCD(LCD_LINE_2, "(%s)", getCouleur());
}
bout = pressedIHM(IHM_REFRESH_INTERVAL);
if (bout == rouge) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Calibrage...");
delay(3000); // TODO
lastCalibrage = clock();
printToLCD(LCD_LINE_1, "Calibrage...");
delay(3000); // TODO
lastCalibrage = clock(); // TODO struct timespec
} else if (bout == jaune) {
break;
}
@ -195,14 +199,12 @@ void* TaskIHM(void* pdata)
// Diagnostics
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Diagnostiquer");
printToLCD(LCD_LINE_1, "Diagnostiquer");
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Diagnostics...");
printToLCD(LCD_LINE_1, "Diagnostics...");
delay(3000); // TODO
} else if (bout == jaune) {
break;
@ -212,22 +214,16 @@ void* TaskIHM(void* pdata)
// Parcours
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Lancer parcours");
gotoLCD(LCD_LINE_2);
printLCD("(");
printCouleur();
printLCD(")");
printToLCD(LCD_LINE_1, "Lancer parcours");
printfToLCD(LCD_LINE_2, "(%s)", getCouleur());
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)");
printToLCD(LCD_LINE_1, "Inserez tirette");
printToLCD(LCD_LINE_2, "(ROUGE: ignorer)");
bout = pressedIHM(IHM_REFRESH_INTERVAL);
if (bout == rouge) {
break;
@ -277,14 +273,12 @@ void* TaskIHM(void* pdata)
// RàZ
for (;;) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Remettre a zero");
printToLCD(LCD_LINE_1, "Remettre a zero");
bout = pressedIHM(IHM_BLOCK);
if (bout == rouge) {
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Remise a zero...");
printToLCD(LCD_LINE_1, "Remise a zero...");
delay(3000); // TODO
} else if (bout == jaune) {
break;
@ -296,6 +290,5 @@ void* TaskIHM(void* pdata)
void deconfigureIHM()
{
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Bye bye!");
printToLCD(LCD_LINE_1, "Bye bye!");
}

View file

@ -1,6 +1,8 @@
#ifndef __IHM_H_
#define __IHM_H_
#include <stdbool.h>
#include "lcd.h"
#define IHM_PIN_ROUGE 0
@ -22,6 +24,8 @@ void deconfigureIHM();
// Private
void* TaskIHM(void *pdata);
void* TaskStdinIHM(void *pdata);
enum boutons pressedIHM(int timeout); // timeout: ms or -1
bool debunkButtonIHM(int pin);
#endif

View file

@ -1,4 +1,7 @@
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
@ -7,6 +10,9 @@
int lcdFd;
pthread_mutex_t sLCD;
char virtual[LCD_NB_TOTAL];
uint8_t pos;
void initLCD()
{
lcdFd = openI2C(LCD_ADDR);
@ -17,23 +23,41 @@ void initLCD()
sendLCD(0x06, LCD_MODE_CMD); // Cursor move direction
sendLCD(0x0C, LCD_MODE_CMD); // Blink Off
sendLCD(0x28, LCD_MODE_CMD); // Data length, number of lines, font size
sendLCD(0x01, LCD_MODE_CMD); // Clear display
clearLCD();
delayMicroseconds(500);
}
void clearLCD()
{
lockLCD();
sendLCD(0x01, LCD_MODE_CMD);
sendLCD(0x02, LCD_MODE_CMD);
for (int i = 0; i < LCD_NB_TOTAL; i++) {
virtual[i] = ' ';
}
unlockLCD();
}
void gotoLCD(uint8_t line)
{
if (line >= LCD_LINE_2) {
pos = 1 * LCD_NB_CHARS + line - LCD_LINE_2;
} else if (line >= LCD_LINE_1) {
pos = 0 * LCD_NB_CHARS + line - LCD_LINE_1;
} else {
pos = LCD_NB_TOTAL;
}
sendLCD(line, LCD_MODE_CMD);
}
void charLCD(char c)
{
if (pos >= 0 && pos < LCD_NB_TOTAL) {
virtual[pos] = c;
}
pos++;
sendLCD(c, LCD_MODE_CHR);
}
@ -45,6 +69,51 @@ void printLCD(char* s)
}
}
void displayLCD()
{
printf("\n");
for (int i = 0; i < LCD_NB_CHARS; i++) {
printf("");
}
printf("\n");
for (int y = 0; y < LCD_NB_LINES; y++) {
printf("");
for (int x = 0; x < LCD_NB_CHARS; x++) {
putchar(virtual[y * LCD_NB_CHARS + x]);
}
printf("\n");
}
printf("");
for (int i = 0; i < LCD_NB_CHARS; i++) {
printf("");
}
printf("\n");
}
void printToLCD(uint8_t line, char* s)
{
lockLCD();
gotoLCD(line);
printLCD(s);
displayLCD();
unlockLCD();
}
void printRightLCD(uint8_t line, char* s)
{
printToLCD(line + LCD_NB_CHARS - strlen(s), s);
}
void printfToLCD(uint8_t line, char* s, ...)
{
char buffer[LCD_NB_TOTAL];
va_list args;
va_start(args, s);
vsnprintf(buffer, LCD_NB_TOTAL, s, args);
va_end(args);
printToLCD(line, buffer);
}
void sendLCD(uint8_t bits, uint8_t mode)
{
lockI2C();

View file

@ -9,6 +9,11 @@
#define LCD_MODE_CHR 1
#define LCD_MODE_CMD 0
#define LCD_NB_LINES 2
#define LCD_NB_CHARS 16
#define LCD_NB_TOTAL LCD_NB_LINES*LCD_NB_CHARS
#define LCD_LINE_1 0x80 // 1st line
#define LCD_LINE_2 0xC0 // 2nd line
@ -21,15 +26,18 @@
// Public
void initLCD();
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();
void printToLCD(uint8_t line, char* s);
void printRightLCD(uint8_t line, char* s);
void printfToLCD(uint8_t line, char* s, ...);
// Private
void sendLCD(uint8_t bits, uint8_t mode);
void toggleEnableLCD(uint8_t bits);
void gotoLCD(uint8_t line);
void charLCD(char c);
void printLCD(char* s);
void displayLCD();
void lockLCD();
void unlockLCD();
#endif

View file

@ -11,8 +11,8 @@
#define PWM_MAX 1023
#define PWM_MAX_V 3.3
// #define TESTINATOR
#define TLE5206
#define TESTINATOR
// #define TLE5206
#ifdef TESTINATOR
#define MOT_MIN_V 0.1
@ -26,16 +26,14 @@
// Pins definition
// Left
// Physical 32
#define ENA 26
#define IN1 2
#define IN2 3
#define IN1 21
#define IN2 22
// Physical 33
// Right
#define ENB 23
#define IN3 4
#define IN4 5
#define IN3 24
#define IN4 25
void configureMovement();

View file

@ -1,16 +1,15 @@
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include "parcours.h"
#include "movement.h"
#include "position.h"
#include "points.h"
#include "lcd.h"
#include "movement.h"
#include "parcours.h"
#include "points.h"
#include "position.h"
pthread_t tParcours;
bool isOrange;
char tempLine[16];
struct timespec tempsStart;
struct timespec tempsNow;
struct timespec tempsEcoule;
@ -19,35 +18,24 @@ 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");
printfToLCD(LCD_LINE_1, "--:--/%2d:%02d", TEMPS_PARCOURS / 60, TEMPS_PARCOURS % 60);
printRightLCD(LCD_LINE_1, "ATT");
resetPoints();
showPoints();
gotoLCD(LCD_LINE_2 + 16 - 3);
printLCD(isOrange ? "Org" : "Vrt");
printRightLCD(LCD_LINE_2, 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();
printRightLCD(LCD_LINE_1, " ");
}
void updateTimeDisplay()
{
lockLCD();
gotoLCD(LCD_LINE_1);
sprintf(tempLine, "%2ld:%02ld", tempsEcoule.tv_sec / 60, tempsEcoule.tv_sec % 60);
printLCD(tempLine);
unlockLCD();
printfToLCD(LCD_LINE_1, "%2ld:%02ld", tempsEcoule.tv_sec / 60, tempsEcoule.tv_sec % 60);
}
int updateParcours()
@ -76,62 +64,43 @@ void stopParcours()
stop();
updateTimeDisplay();
gotoLCD(LCD_LINE_1 + 16 - 3);
printLCD("FIN");
printRightLCD(LCD_LINE_1, "FIN");
showPoints();
}
#define UP_TIME 1000
#define HIGH_TIME 30000
#define DOWN_TIME 1000
#define LOW_TIME 2000
#define MAX_VIT MOT_MAX_V
void* TaskParcours(void* pdata)
{
(void)pdata;
for (;;) {
delay(250);
addPoints(1);
for (int i = 0; i < UP_TIME; i++) {
float p = (float)i / (float)UP_TIME;
changerMoteurs(p * MOT_MAX_V, p * MOT_MAX_V);
delay(1);
}
addPoints(1);
changerMoteurs(MOT_MAX_V, MOT_MAX_V);
delay(HIGH_TIME);
addPoints(1);
for (int i = 0; i < DOWN_TIME; i++) {
float p = (float)i / (float)DOWN_TIME;
p = 1 - p;
changerMoteurs(p * MOT_MAX_V, p * MOT_MAX_V);
delay(1);
}
addPoints(1);
changerMoteurs(0, 0);
delay(LOW_TIME);
}
}
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;
}

View file

@ -3,7 +3,6 @@
#include "lcd.h"
int points;
char tempLine[16];
void resetPoints()
{
@ -17,11 +16,7 @@ int getPoints()
void showPoints()
{
sprintf(tempLine, "%d points", getPoints());
lockLCD();
gotoLCD(LCD_LINE_2);
printLCD(tempLine);
unlockLCD();
printfToLCD(LCD_LINE_2, "%d points", getPoints());
}
void addPoints(int pts)

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

@ -0,0 +1,31 @@
/* Teste si une broche est connecté à une autre */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPiI2C.h>
#include "lcd.h"
#include "movement.h"
int main(int argc, char* argv[])
{
(void)argc;
(void)argv;
initI2C();
initLCD();
clearLCD();
printToLCD(LCD_LINE_1, "Forward");
configureMovement();
for (;;) {
changerMoteurs(1.5, 2);
sleep(1);
}
}

View file

@ -6,7 +6,6 @@
#include <unistd.h>
#include <wiringPiI2C.h>
#include "srf08.h"
#include "i2c.h"
#include "lcd.h"
@ -17,34 +16,9 @@ int main(int argc, char* argv[])
(void)argv;
initI2C();
// Adresse du SRF05
uint8_t address = atoi(argv[1]);
printf("Connecting to %d (0x%x)\n", address, address);
initLCD();
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Distance");
int front = openSRF08(address);
char line[16];
float l = 0;
for (;;) {
startSRF08(front);
gotoLCD(LCD_LINE_2);
printf("l = %3f\n", l);
sprintf(line, "%f mm", l);
printLCD(line);
printLCD(" ");
waitSRF08(front);
l = getSRF08(front);
}
printLCD("Bojour");
}

View file

@ -91,7 +91,8 @@ upgrade-filesystem: sshconf configure
# Met jour les overlays (une partie des fichiers)
upgrade-overlays: sshconf
ssh -F sshconf principal true
rsync --rsh 'ssh -F sshconf' --archive --chown root:root robotech/chef/rootfs_overlay/ principal:/
chmod 700 board/robotech/cdfprincipal/rootfs_overlay/root
rsync --rsh 'ssh -F sshconf' --archive --chown root:root board/robotech/cdfprincipal/rootfs_overlay/ principal:/
# ARDUINO
upgrade-arduino:
@ -116,6 +117,11 @@ upgrade-chef: chef
rsync --rsh 'ssh -F sshconf' --archive --chown root:root buildroot/output/target/opt/chef principal:/opt/
run:
ssh -F sshconf principal true
ssh -F sshconf principal /etc/init.d/S50chef stop
ssh -F sshconf principal 'cd /opt/chef; bin/premier; /opt/chef/lcdOff.sh'
restart:
ssh -F sshconf principal true
ssh -F sshconf principal /etc/init.d/S50chef restart

View file

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

View file

@ -3,19 +3,22 @@
# Start main program
#
EXEC=$(which sh)
SHELL=$(which sh)
EXECDIR=/opt/chef
EXECNAME=premier
EXECPATH=bin/$EXECNAME
PIDFILE=/var/run/chef.pid
LOGFILE=/var/run/chef.log
start() {
printf "Starting chef: "
start-stop-daemon -p "$PIDFILE" -x "$EXEC" -b -m -S -- "/opt/chef/run.sh" -l "$LOGFILE"
echo "OK"
cd "$EXECDIR"; /sbin/start-stop-daemon -p "$PIDFILE" -x "$EXECPATH" -b -m -S
echo "OK"
}
stop() {
printf "Stopping chef: "
start-stop-daemon -p "$PIDFILE" -x "$EXEC" -K
/sbin/start-stop-daemon -x "$EXECPATH" -K
/opt/chef/lcdOff.sh
echo "OK"
}

View file

@ -5,10 +5,7 @@
start() {
printf "Starting extra services: "
# if ! /opt/cdf/bin/testpin 0 1
# then
/etc/extra.d/rcS
# fi
/etc/extra.d/rcS
echo "OK"
}