Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- elpatosilva
- Date:
- 2019-10-26
- Revision:
- 0:749a196e6ebe
- Child:
- 1:6e374a9b1bf5
File content as of revision 0:749a196e6ebe:
#include "mbed.h"
#include "lib/Pserial.h"
#include "lib/Servo.h"
#include "lib/Sensor.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Conf IO
DigitalOut led1(LED1); // HeartBeat
PwmOut cg90(PTD1);
AnalogIn opticLeftIn(PTB2);
AnalogIn opticRigthIn(PTB3);
DigitalOut ultrasonicTrigger(PTA1);
DigitalIn ultrasonicEcho(PTB9);
DigitalIn speedLeft(PTA2);
DigitalIn speedRigth(PTB23);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Timers y relacionados
Ticker timer100ms;
LowPowerTimer timer1ms;
uint32_t maxUsTicker;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Prototipos locales
void heartBeat();
void heartBeatSetFlag();
void serialReceivePc();
void cmdExec();
void sendOpticData();
void sendUltrasonicData();
void sendSpeedData();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constantes locales
// Version del FW
const uint8_t FIRMWARE_VERSION[] = "V0.03";
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Definiciones locales
// Estructura para uso auxiliar. Arduino es little endian
typedef union{
uint8_t u8[4];
uint16_t u16[2];
int8_t i8[2];
uint32_t u32;
int32_t i32;
}_work;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Variables y objetos Locales
Serial pc(USBTX, USBRX, 19200);
_Pserial pserial;
_Sensor rigthOpticSensor;
_Sensor leftOpticSensor;
_Sensor ultrasonicSensor;
_Sensor rigthSpeedSensor;
_Sensor leftSpeedSensor;
_Servo servo;
//_Motor motorLeft
//_Motor motorRigth
/*
* Control de los sensores, tiempos de muestreo
*/
uint16_t opticTimeInterval;
uint16_t ultrasonicTimeInterval;
uint16_t motorSpeedTimeInterval;
// Auxiliar
_work work;
// Flag del heartBeat()
bool heartBeatFlag;
extern _txbuffer TX;
extern _rxbuffer RX;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////// MAIN
int main(){
maxUsTicker = us_ticker_read();
timer100ms.attach(&heartBeatSetFlag, 0.1);
heartBeatFlag = false;
timer1ms.start();
setup(&rigthOpticSensor, &opticRigthIn);
setup(&leftOpticSensor, &opticLeftIn);
setup(&ultrasonicSensor, &ultrasonicTrigger, &ultrasonicEcho);
setup(&rigthSpeedSensor, &speedRigth);
setup(&leftSpeedSensor, &speedLeft);
opticTimeInterval = 0;
ultrasonicTimeInterval = 0;
motorSpeedTimeInterval = 0;
pc.attach(&serialReceivePc, Serial::RxIrq);
serialSetup(&pserial, &pc);
setup(&servo, &cg90);
while(1){
// heartBeat
if(heartBeatFlag) heartBeat();
// Overflow de us_ticker_read(), reseteo todo lo que utiliza este dato
if(maxUsTicker > us_ticker_read()){
maxUsTicker = us_ticker_read();
serialCmdClean(&pserial);
}
// envio datos que pueda haber en el buffer de salida
serialSubmit(&pserial);
// proceso comando presente en el buffer
if(pserial.RX.cmd)
cmdExec();
// Busco si hay un nuevo header en el buffer
serialGetFrame(&pserial);
// Ejecuto tareas de sensores
if(opticTimeInterval){
sendOpticData();
}
if(ultrasonicTimeInterval){
sendUltrasonicData();
}
if(motorSpeedTimeInterval){
sendSpeedData();
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Funciones locales
/*
* Interrupcion, datos en el puerto serie con la PC
*/
void serialReceivePc(){
serialReceive(&pserial);
}
void serialRecevePc(_Pserial *);
/*
* Señal de activo, dos parpadeos de 100ms cada dos segundos
*/
void heartBeatSetFlag(){
heartBeatFlag = true;
}
void heartBeat(){
static int count = 0;
switch (count++){
case 0:
case 2:
led1 = 0;
break;
case 1:
case 3:
led1 = 1;
break;
case 20:
count = 0;
break;
}
heartBeatFlag = false;
}
/*
* Envio datos del sensor optico a la velocidad especificada
*/
void sendOpticData(){
static unsigned long stime = timer1ms.read_ms();
if(timer1ms.read_ms() > stime+(opticTimeInterval*10)){
work.u16[0] = opticTimeInterval;
serialEnqueueHeader(&pserial, 12);
serialEnqueueData(&pserial, 0xA0); // Comando
serialEnqueueData(&pserial, work.u8[0]); // Intervalo actual (2 bytes)
serialEnqueueData(&pserial, work.u8[1]);
serialEnqueueData(&pserial, 0); // Sensor exterior izquierdo (2 bytes)
serialEnqueueData(&pserial, 0);
work.u16[0] = getValue(&leftOpticSensor);
work.u16[1] = getValue(&rigthOpticSensor);
serialEnqueueData(&pserial, work.u8[0]); // Sensor interior izquierdo (2 bytes)
serialEnqueueData(&pserial, work.u8[1]);
serialEnqueueData(&pserial, work.u8[2]); // Sensor interior drecho (2 bytes)
serialEnqueueData(&pserial, work.u8[3]);
serialEnqueueData(&pserial, 0); // Sensor exterior derecho (2 bytes)
serialEnqueueData(&pserial, 0);
serialEnqueueChksum(&pserial);
stime = timer1ms.read_ms();
}
}
/*
* Envio datos del sensor ultrasonico a la velocidad especificada
* Los tiempos de llamada deberian estar espaciados al menos 50ms
*/
void sendUltrasonicData(){
static uint32_t stime = timer1ms.read_ms();
static bool inProgress = false;
if(inProgress){
uint16_t distance = isReady(&ultrasonicSensor);
if(distance){ // Ya tengo la distancia, la envio
work.u16[0] = ultrasonicTimeInterval;
serialEnqueueHeader(&pserial, 12);
serialEnqueueData(&pserial, 0xA1); // Comando
serialEnqueueData(&pserial, work.u8[0]); // Intervalo actual (2 bytes)
serialEnqueueData(&pserial, work.u8[1]);
work.u16[0] = ultrasonicTimeInterval;
serialEnqueueData(&pserial, work.u8[0]); // Distancia medida (2 bytes)
serialEnqueueData(&pserial, work.u8[1]);
serialEnqueueChksum(&pserial);
inProgress = false;
}
}
if(timer1ms.read_ms() > stime+(opticTimeInterval*10)){
reset(&ultrasonicSensor);
inProgress = init(&ultrasonicSensor);
stime = timer1ms.read_ms();
}
}
void sendSpeedData(){}
/*
* Se ha recibido un comando por puerto serie, lo interpreto y respondo
* Si no hay lugar en el buffer lo espero TXCMDTIME us
*/
void cmdExec(){
bool ok = false;
switch(pserial.RX.buf[pserial.RX.cmdIndex]){
// ping
case 0xF0:{
ok = serialEnqueueHeader(&pserial, 3) && serialEnqueueData(&pserial, 0xF0) && serialEnqueueData(&pserial, 0x0D) && serialEnqueueChksum(&pserial);
break;
}
// Version de Firmware
case 0xF1:{
ok = serialEnqueueHeader(&pserial, 13+sizeof(FIRMWARE_VERSION)+sizeof(__DATE__)+sizeof(__TIME__)) && serialEnqueueData(&pserial, 0xF1);
for (int i = 0 ; i < sizeof(FIRMWARE_VERSION) ; i++)
ok = ok && serialEnqueueData(&pserial, FIRMWARE_VERSION[i]);
ok = ok && serialEnqueueData(&pserial, '_') && serialEnqueueData(&pserial, 'b') && serialEnqueueData(&pserial, 'u') && serialEnqueueData(&pserial, 'i') && serialEnqueueData(&pserial, 'l') && serialEnqueueData(&pserial, 'd') && serialEnqueueData(&pserial, '_');
for (int i = 0 ; i < sizeof(__DATE__) ; i++)
ok = ok && serialEnqueueData(&pserial, __DATE__[i]);
ok = ok && serialEnqueueData(&pserial, '_') && serialEnqueueData(&pserial, 'a') && serialEnqueueData(&pserial, 't') && serialEnqueueData(&pserial, '_');
for (int i = 0 ; i < sizeof(__TIME__) ; i++)
ok = ok && serialEnqueueData(&pserial, __TIME__[i]);
ok = ok && serialEnqueueChksum(&pserial);
break;
}
// Sensores Opticos
case 0xA0:{
work.u8[0] = pserial.RX.buf[pserial.RX.cmdIndex+1];
work.u8[1] = pserial.RX.buf[pserial.RX.cmdIndex+2];
opticTimeInterval = work.u16[0];
ok = true;
break;
}
// Sensor Ultrasonico
case 0xA1:{
work.u8[0] = pserial.RX.buf[pserial.RX.cmdIndex+1];
work.u8[1] = pserial.RX.buf[pserial.RX.cmdIndex+2];
ultrasonicTimeInterval = work.u16[0];
ok = true;
break;
}
// Sensores de horquilla
case 0xA4:{
work.u8[0] = pserial.RX.buf[pserial.RX.cmdIndex+1];
work.u8[1] = pserial.RX.buf[pserial.RX.cmdIndex+2];
motorSpeedTimeInterval = work.u16[0];
ok = true;
break;
}
default:{
ok = serialEnqueueHeader(&pserial, 2) && serialEnqueueData(&pserial, 0xFF) && serialEnqueueChksum(&pserial);
}
}
if (ok || us_ticker_read() > pserial.TX.cmdTime + TXCMDTIME){
pserial.RX.cmd = false;
pserial.RX.indexR = pserial.RX.cmdIndex+pserial.RX.payloadSize;
pserial.TX.cmdTime = 0;
}
}