1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2025-09-04 01:05:56 +02:00

Arduino↔Chef: Ajout côté chef & corrections

This commit is contained in:
Geoffrey Frogeye 2018-02-16 15:44:45 +01:00
parent 0a9009d0c3
commit 45151e7b1a
25 changed files with 669 additions and 166 deletions

View file

@ -5,7 +5,7 @@ CC=gcc
# Bibliothèques
LIBS=
## Drapeaux pour le linker
LDFLAGS=
LDFLAGS=-lpthread
## Drapeaux pour le compilateur
CFLAGS=
## Générateurs de drapeaux pour les bibliothèques
@ -37,7 +37,7 @@ endif
default: bin/testpin bin/premier
# Binaires (dont il faut spécifier les objets explicitement)
bin/premier: obj/common.o obj/serial.o
bin/premier: obj/CA.o obj/debug.o obj/movement.o
bin/testPin: obj/testPin.o
$(CC) $(LDFLAGS) $^ -lwiringPi -o $@

178
chef/src/CA.c Normal file
View file

@ -0,0 +1,178 @@
#include "CA.h"
#include <fcntl.h> // O_*
#include <stdio.h> // printf...
#include <stdlib.h> // stuff
#include <string.h> // memcpy
#include <strings.h> // bzero
#include <unistd.h> // read(), write()...
void printData(void* data, size_t size)
{
printf(" ");
unsigned char* p = data;
for (size_t i = 0; i < size; i++) {
if (*p >= ' ' && *p <= '~') {
printf(" %c", *p);
} else {
printf(" %02x", *p);
}
p++;
}
printf("\n");
}
void configureArduino()
{
// Connection au port série
printf("Connexion à %s... ", ARDUINO_PORTNAME);
arduino = open(ARDUINO_PORTNAME, O_RDWR | O_NOCTTY | O_NDELAY);
if (arduino < 0) {
printf("Échec !\n");
exit(1);
}
// Configuration du port série
struct termios cfg;
bzero(&cfg, sizeof(cfg));
cfg.c_cflag = CLOCAL | CREAD | CA_BAUDRATE | CS8;
cfg.c_iflag = 0;
cfg.c_oflag = 0;
cfg.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
cfg.c_cc[VTIME] = 0; /* inter-character timer unused */
cfg.c_cc[VMIN] = 1; /* blocking read until 1 char received */
if (tcsetattr(arduino, TCSANOW, &cfg) < 0) {
perror("serialConfig.tcsetattr");
exit(1);
}
sleep(1);
// Flush
unsigned char trash[1024];
read(arduino, &trash, sizeof(trash));
printf("OK!\n");
}
void deconfigureArduino()
{
close(arduino);
printf("Déconnecté\n");
}
void registerRxHandler(unsigned char code, rxHandler handler)
{
rxHandlersAC[code] = handler;
}
void* TaskReaderAC(void* pdata)
{
(void)pdata;
unsigned char code;
for (;;) {
code = readByteCA();
#ifdef PRINTRAWDATA
printf("");
printData(&code, sizeof(code));
#endif
rxHandler handler = rxHandlersAC[code];
if (handler != NULL) {
handler();
} else {
printf("Code inconnu: %x (%c)\n", code, code);
}
}
return NULL;
}
void onA2CD_ERR()
{
struct A2CD_ERRs s;
readCA(&s, sizeof(struct A2CD_ERRs));
printf("Erreur reçue : %c (%2x)\n", s.code, s.code);
}
void configureCA()
{
configureArduino();
for (int i = 0; i < 256; i++) {
rxHandlersAC[i] = NULL;
}
pthread_mutex_init(&sSendCA, NULL);
pthread_create(&tReaderAC, NULL, TaskReaderAC, NULL);
registerRxHandler(A2CD_ERR, onA2CD_ERR);
}
void deconfigureCA()
{
deconfigureArduino();
}
void sendByteCA(unsigned char data)
{
write(arduino, &data, sizeof(data));
#ifdef PRINTRAWDATA
printf("");
printData(&data, sizeof(data));
#endif
}
void sendCA(unsigned char code, void* data, size_t size)
{
pthread_mutex_lock(&sSendCA);
sendByteCA(code);
if (size > 0) {
unsigned char* p = data;
for (size_t i = 0; i < size; i++) {
write(arduino, p, sizeof(unsigned char));
p++;
}
// Envoyer plus d'un octet d'un coup curieusement il aime pas ça du tout
}
pthread_mutex_unlock(&sSendCA);
#ifdef PRINTRAWDATA
if (size > 0) {
printf("");
printData(data, size);
}
#endif
}
unsigned char readByteCA()
{
unsigned char c;
while (read(arduino, &c, sizeof(c)) < 1) {
sleep(0);
}
return c;
#ifdef PRINTRAWDATA
printf("");
printData(&c, sizeof(c));
#endif
}
void readCA(void* data, size_t size)
{
size_t remaining = size;
int justRead;
char* p = data;
do {
justRead = read(arduino, p, remaining);
if (justRead > 0) {
p += justRead;
remaining -= justRead;
}
} while (remaining > 0);
#ifdef PRINTRAWDATA
printf("");
printData(data, size);
#endif
}

29
chef/src/CA.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef __AC_H_
#define __AC_H_
#include <sys/ioctl.h>
#include <pthread.h>
#include <termios.h> // baudrates
#include "ACsignals.h"
#define ARDUINO_PORTNAME "/dev/ttyACM0"
#define CA_BAUDRATE B9600
// #define PRINTRAWDATA
int arduino;
pthread_mutex_t sSendCA;
pthread_t tReaderAC;
typedef void (*rxHandler)(void);
rxHandler rxHandlersAC[256];
void registerRxHandler(unsigned char code, rxHandler handler); // À utiliser après configureCA();
void sendByteCA(unsigned char data); // Privé
void sendCA(unsigned char code, void* data, size_t size);
unsigned char readByteCA(); // À utiliser uniquement depuis un rxHandler
void readCA(void* data, size_t size); // À utiliser uniquement depuis un rxHandler
void configureCA();
void deconfigureCA();
#endif

View file

@ -1 +0,0 @@
#include "common.h"

View file

@ -1,10 +0,0 @@
#ifndef __COMMON_H_
#define __COMMON_H_
#include <stdlib.h>
#include <stdio.h>
#define SIGNAL_AVANCER 42
#endif

52
chef/src/debug.c Normal file
View file

@ -0,0 +1,52 @@
#include "debug.h"
#include <stdio.h>
#include <unistd.h> // sleep
void* TaskDebug(void* pdata)
{
(void)pdata;
struct timespec tim;
/* tim.tv_sec = 0; */
/* tim.tv_nsec = 100000000L; */
tim.tv_sec = 1;
tim.tv_nsec = 0;
for (;;) {
nanosleep(&tim, NULL);
sendCA(A2CI_DBG, NULL, 0);
}
return NULL;
}
void printDebugInfos(struct A2CI_DBGs* debug)
{
printf("← Position actuelle (%f; %f) (%f°)", debug->actuel.x, debug->actuel.y, debug->actuel.o);
printf(", destination : ");
if (debug->movement == C2AD_STOP) {
printf("aucune\n");
} else {
printf("(%f; %f) (%f°)\n", debug->destination.x, debug->destination.y, debug->destination.o);
}
}
void onA2CI_DBG()
{
readCA(&debug, sizeof(struct A2CI_DBGs));
printDebugInfos(&debug);
}
void configureDebug()
{
registerRxHandler(A2CI_DBG, onA2CI_DBG);
#ifdef REGULARREPORTS
pthread_create(&tDebug, NULL, TaskDebug, NULL);
#endif
}
void deconfigureDebug()
{
#ifdef REGULARREPORTS
pthread_cancel(tDebug);
#endif
}

16
chef/src/debug.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef __DEBUG_H_
#define __DEBUG_H_
#include <pthread.h>
#include "CA.h"
#define REGULARREPORTS
struct A2CI_DBGs debug;
pthread_t tDebug;
void* TaskDebug(void *pdata);
void onA2CI_DBG();
void configureDebug();
void deconfigureDebug();
#endif

55
chef/src/movement.c Normal file
View file

@ -0,0 +1,55 @@
#include "movement.h"
#include "CA.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void onC2AD_STOP()
{
// On considère que l'arrêt se fait très rapidement pour ne pas
// avoir à attendre le signal de retour de C2AD_STOP
}
void stop()
{
printf("→ Arrêt\n");
sendCA(C2AD_STOP, NULL, 0);
registerRxHandler(C2AD_STOP, onC2AD_STOP);
}
// Inspiré de https://stackoverflow.com/a/1760819
pthread_mutex_t reponseMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t reponseCond = PTHREAD_COND_INITIALIZER;
bool attenteReponse = false;
void onC2AD_GOTO()
{
pthread_mutex_lock(&reponseMutex);
attenteReponse = false;
pthread_cond_signal(&reponseCond);
pthread_mutex_unlock(&reponseMutex);
}
void aller(struct position* pos)
{
printf("→ Déplacement vers (%f; %f) (%f°)\n", pos->x, pos->y, pos->o);
if (attenteReponse) {
printf("Déjà en déplacement !\n");
exit(EXIT_FAILURE);
}
attenteReponse = true;
registerRxHandler(C2AD_GOTO, onC2AD_GOTO);
sendCA(C2AD_GOTO, (struct C2AD_GOTOs*)pos, sizeof(struct C2AD_GOTOs));
pthread_mutex_lock(&reponseMutex);
while (attenteReponse) {
pthread_cond_wait(&reponseCond, &reponseMutex);
}
pthread_mutex_unlock(&reponseMutex);
registerRxHandler(C2AD_GOTO, NULL);
printf("← Arrivé à destination\n");
}

9
chef/src/movement.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef __MOVEMENT_H_
#define __MOVEMENT_H_
#include "CA.h"
void stop();
void aller(struct position* pos);
#endif

View file

@ -1,15 +1,59 @@
#include "premier.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h> // random seed
#include <pthread.h>
#include <unistd.h> // sleep
#include "serial.h"
#include "CA.h"
#include "movement.h"
#include "debug.h"
#define TEMPSMAX 10
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);
stop();
sleep(2);
}
printf("Fin du parcours\n");
return NULL;
}
int main()
{
unsigned char g;
printf("Démarrage...\n");
configureCA();
sendByteCA('c');
while ((g = readByteCA())) {
printf("%c\n", g);
}
configureDebug();
srand(time(NULL));
/* printf("Synchronisation avec le Raspberry Pi\n"); // TODO */
/* 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); */
/* stop(); */
/* */
deconfigureDebug();
deconfigureCA();
return 0;
return EXIT_SUCCESS;
}

View file

@ -1,5 +0,0 @@
#ifndef __PREMIER_H_
#include "common.h"
#endif

View file

@ -1,58 +0,0 @@
#include "serial.h"
#include <stdio.h> // printf...
#include <stdlib.h> // stuff
#include <unistd.h> // read(), write()...
#include <fcntl.h> // O_*
#include <strings.h> // bzero
#include "common.h"
void configureCA()
{
// Connection au port série
printf("Connexion à %s... ", ARDUINO_PORTNAME);
arduino = open(ARDUINO_PORTNAME, O_RDWR | O_NOCTTY | O_NDELAY);
if (arduino < 0) {
printf("Échec !\n");
exit(1);
}
// Configuration du port série
struct termios cfg;
bzero(&cfg, sizeof(cfg));
cfg.c_cflag = CLOCAL | CREAD | CA_BAUDRATE | CS8;
cfg.c_iflag = 0;
cfg.c_oflag = 0;
cfg.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
cfg.c_cc[VTIME] = 0; /* inter-character timer unused */
cfg.c_cc[VMIN] = 1; /* blocking read until 1 char received */
if (tcsetattr(arduino, TCSANOW, &cfg) < 0) {
perror("serialConfig.tcsetattr");
exit(1);
}
sleep(1);
printf("OK!\n");
}
void deconfigureCA() {
close(arduino);
}
void sendByteCA(unsigned char data) {
write(arduino, &data, sizeof(data));
}
void sendCA(unsigned char code, void* data, size_t size)
{
sendByteCA(code);
write(arduino, data, size);
}
unsigned char readByteCA() {
unsigned char c;
while (read(arduino, &c, sizeof(c)) < 1) {
}
return c;
}

View file

@ -1,19 +0,0 @@
#ifndef __SERIAL_H_
#define __SERIAL_H_
#include <sys/ioctl.h>
#include <termios.h> // baudrates
#include "ACsignals.h"
#define ARDUINO_PORTNAME "/dev/ttyACM0"
#define CA_BAUDRATE B9600
int arduino;
void configureCA();
void deconfigureCA();
void sendByteCA(unsigned char data);
unsigned char readByteCA();
#endif