Autor Tema: Placa multisensor IR (detector obstaculos)  (Leído 2973 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado splasma2

  • PIC16
  • ***
  • Mensajes: 131
Placa multisensor IR (detector obstaculos)
« en: 24 de Enero de 2013, 18:15:14 »
Hola de nuevo.

Por si a alguien le puede ser util, os voy a mostrar un mini-proyecto que he hecho para controlar hasta 5 detectores de obstaculos usando el TCRT5000 ( Reflective Optical Sensor) y 2 detectores de contacto. Esta placa forma parte de un proyecto mayor, un robot 4WD controlado por una placa ARM Stellaris Cortex LM4F120 de TI.

La placa, como digo, controla hasta 5 sensores, para ello he optado por usar 5 entradas analogicas de un PIC18F1320 que leen la salida de cada sensor, secuencialmente el led de cada sensor se activa durante un periodo corto de tiempo, aprox. 1 ms, de forma que puedo por medio de un transistor darle caña, mas de  100 mA, con esto "creo" que aumento un poco el alcance sin afectar mucho el tiempo de vida del LED,( espero  :shock:)  aun así el alcance no es mucho 4-5 cm, y depende del color del objeto que este delante... Si alguien esta preocupado por la intensidad que pasa por  el LED, siempre se puede aumentar la resistencia que le alimenta, yo uso una 22 ohmios.

Despues de leer con el ADC cada salida,se compara con un valor de referencia  que se ha establecido previamente: 2/3 del valor que se lee al comenzar el programa,  considero que es el valor que da el sensor cuando no hay nada delante. El criterio es : si el valor leido es inferior a esta referencia  se ha detectado obstaculo por ese sensor.

Después de esto, se codifica el valor de cada sensor (1:detectado obstaculo, 0 : no detectado) en cada bit de un byte que se envia siguiendo el protocolo SPI ( esto aún no está probado). Este dato por SPI es lo que debe leer la placa madre ARM, y despues de esto, vuelta a empezar....


El esquema simplicado que usado para probarlo con Proteus es este:




« Última modificación: 24 de Enero de 2013, 19:02:55 por splasma2 »

Desconectado splasma2

  • PIC16
  • ***
  • Mensajes: 131
Re: Placa multisensor IR (detector obstaculos)
« Respuesta #1 en: 24 de Enero de 2013, 19:06:10 »
Y ahora el código (HiTech) , que aproveche...:
Código: [Seleccionar]
#include <pic18.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <adc.h>

#include "delay.h"

#ifdef _18F1320

#pragma config OSC = INTIO2
#pragma config PWRT = ON
#pragma config WDT = OFF
#pragma config MCLRE = OFF
#pragma config BOR = OFF

#endif

// ADC IR Sensor Inputs
#define AN0_IR_SENSOR1  RA0
#define AN1_IR_SENSOR2  RA1
#define AN2_IR_SENSOR3  RA2
#define AN3_IR_SENSOR4  RA3
#define AN4_IR_SENSOR5  RB0

// Contact Sensor Inputs
#define IN_CS_SENSOR1  RB6
#define IN_CS_SENSOR2  RA4

// Driver IR Sensor Inputs
#define OUT_S1 LATBbits.LB7
#define OUT_S2 LATBbits.LB2
#define OUT_S3 LATBbits.LB3
#define OUT_S4 LATAbits.LA7
#define OUT_S5 LATBbits.LB1

// LED status
#define LED LATAbits.LA6

// I/F main processor
#define SPI_SDO LATBbits.LB4
#define SPI_SCK LATBbits.LB5




//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------



//extern unsigned char ftoa(float fnum, unsigned char *str);

void sendSPIData(unsigned char v);
void readIRSensors(unsigned int data[]);

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define SYSCLK          PIC_CLK          // SYSCLK frequency in Hz


//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------



// ======================================
//  InitHW
// ======================================
void InitHW()
{

// ====================
// Clocks
// ====================


OSCCONbits.IRCF = 0b110; // 8 Mhz , no se usa con XT

// ====================
// Ports
// ====================

LATA = 0;
LATB = 0;

TRISA = 0b00111111; // RA0-3 ADC input RA4-5 digital input
TRISB = 0b01000001;     // RB0 ADC input , RB6 digital input


// ====================
// ADCs
// ====================

ADCON0 = 0b00000000; // ADC ref = Vdd,Vss
ADCON1 = 0b01100000; // AN0-AN4 as ADC inputs
ADCON2 = 0b10100101; // Right justify, Fadc= Fosc/16 & 8 TAD ACQ time ( min. 0.7 us)

// ====================
// Pullups
// ====================
RBPU  = 0; // Internal RB Pull-Up activas


}

//
// *--------------------------------------------------------------------------------*
// *--------------------------------------------------------------------------------*
// *--------------------------------------------------------------------------------*

#define N_IR_SENSORS 5

#define RESET_SENSOR {OUT_S1 = 0;OUT_S2 = 0;OUT_S3 = 0;OUT_S4 = 0;OUT_S5=0;}

unsigned int sensor_adc[N_IR_SENSORS];
unsigned int sensor_limit[N_IR_SENSORS];

void main()
{
unsigned char i;
unsigned char dataOut;
char calibrating = 1;


InitHW();

LED=1;
DelayBigMs(400);
LED=0;
DelayBigMs(400);
LED=1;
DelayMs(20);

while(1)
{
if (calibrating)
{
readIRSensors(&sensor_limit);
for ( i = 0; i < N_IR_SENSORS;i++)
{
sensor_limit[i] = (sensor_limit[i] * 3 )/ 4;
}
calibrating= 0;
LED=0;
}
else
{
readIRSensors(&sensor_adc);

dataOut = 0;

for ( i = 0; i < N_IR_SENSORS;i++)
{
if (sensor_adc[i] < sensor_limit[i])
dataOut |= ( 1 << i);
}

if (IN_CS_SENSOR1 == 0) dataOut != 0b01000000;
if (IN_CS_SENSOR2 == 0) dataOut != 0b00100000;

if ( dataOut > 0)
LED = 1;
else
LED = 0;

dataOut |= 0b10000000; // b7 always is 1

sendSPIData(dataOut);
}



}

}
//-----------------------------------------------------------------------------
// Read IR sensors
//-----------------------------------------------------------------------------

#define N_SAMPLES 4
void readIRSensors(unsigned int data[])
{
unsigned char nsample,idxIRSensor;

for (idxIRSensor = 0; idxIRSensor < N_IR_SENSORS; idxIRSensor++)
{
data[idxIRSensor] = 0;
}

for (nsample = 0; nsample < N_SAMPLES;nsample++)
{

  for (idxIRSensor = 0; idxIRSensor < N_IR_SENSORS; idxIRSensor++)
  {

RESET_SENSOR;
switch(idxIRSensor)
{
case 0:
OUT_S1 = 1;
ADCON0=0b00000001; // AN0 Go
break;
case 1:
OUT_S2 = 1;
ADCON0=0b00000101; // AN1 Go
break;
case 2:
OUT_S3 = 1;
ADCON0=0b00001001; // AN2 Go
break;
case 3:
OUT_S4 = 1;
ADCON0=0b00001101; // AN3 Go
break;
case 4:
OUT_S5 = 1;
ADCON0=0b00010001; // AN3 Go
break;

}

DelayMs(1);

ConvertADC();
while (BusyADC());
data[idxIRSensor] += ReadADC();

RESET_SENSOR;

  }
}

for (idxIRSensor = 0; idxIRSensor < N_IR_SENSORS; idxIRSensor++)
{
data[idxIRSensor] = data[idxIRSensor] / N_SAMPLES;
}

}
//-----------------------------------------------------------------------------
// Send SPI Data
//-----------------------------------------------------------------------------

const char mask[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void sendSPIData(unsigned char v)
{
char i;
SPI_SDO = 0;
SPI_SCK = 0;
DelayMs(1);

for ( i = 0; i < 8; i++)
{
SPI_SDO = (( v & mask[i]) > 0);
DelayUs(20);
SPI_SCK = 1;
DelayUs(50);
SPI_SCK = 0;
DelayUs(20);

}

DelayUs(10);
SPI_SDO = 0;
SPI_SCK = 0;



}

// *--------------------------------------------------------------------------------*


Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: Placa multisensor IR (detector obstaculos)
« Respuesta #2 en: 25 de Enero de 2013, 12:39:30 »
Gracias por compartir tu proyecto.. agrego la hoja de datos de los sensores infrarojos
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado splasma2

  • PIC16
  • ***
  • Mensajes: 131
Re: Placa multisensor IR (detector obstaculos)
« Respuesta #3 en: 29 de Enero de 2013, 18:09:57 »
Bueno, ya he probado el SPI y funciona, la placa madre ARM Cortex (SPI slave) ya recibe los datos que le envia la placa multisensor ( SPI master), había algún error en el código anterior, pongo el corregido:

Código: [Seleccionar]
#include <pic18.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <adc.h>

#include "delay.h"

#ifdef _18F1320

#pragma config OSC = INTIO2
#pragma config PWRT = ON
#pragma config WDT = OFF
#pragma config MCLRE = OFF
#pragma config BOR = OFF

#endif

// ADC IR Sensor Inputs
#define AN0_IR_SENSOR1   RA0
#define AN1_IR_SENSOR2   RA1
#define AN2_IR_SENSOR3   RA2
#define AN3_IR_SENSOR4   RA3
#define AN4_IR_SENSOR5   RB0

// Contact Sensor Inputs
#define IN_CS_SENSOR1   RB6
#define IN_CS_SENSOR2   RA5

// Driver IR Sensor Inputs
#define OUT_S1 LATBbits.LB7
#define OUT_S2 LATBbits.LB2
#define OUT_S3 LATBbits.LB3
#define OUT_S4 LATAbits.LA7
#define OUT_S5 LATBbits.LB1

// LED status
#define LED LATAbits.LA6

// I/F main processor
#define SPI_SDO LATBbits.LB5
#define SPI_SCK LATBbits.LB4
#define SPI_SS LATAbits.LA4




//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------



//extern unsigned char ftoa(float fnum, unsigned char *str);

void sendSPIData(unsigned char v);
void readIRSensors(unsigned int data[]);

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define SYSCLK          PIC_CLK          // SYSCLK frequency in Hz


//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------



// ======================================
//  InitHW
// ======================================
void InitHW()
{

// ====================
// Clocks
// ====================


OSCCONbits.IRCF = 0b110; // 8 Mhz , no se usa con XT

// ====================
// Ports
// ====================

LATA = 0;
LATB = 0;

TRISA = 0b00101111; // RA0-3 ADC input RA5 digital input
TRISB = 0b01000001;     // RB0 ADC input , RB6 digital input


// ====================
// ADCs
// ====================

ADCON0 = 0b00000000; // ADC ref = Vdd,Vss
ADCON1 = 0b01100000; // AN0-AN4 as ADC inputs
ADCON2 = 0b10100101; // Right justify, Fadc= Fosc/16 & 8 TAD ACQ time ( min. 0.7 us)

// ====================
// Pullups
// ====================
RBPU  = 0; // Internal RB Pull-Up activas


}

//
// *--------------------------------------------------------------------------------*
// *--------------------------------------------------------------------------------*
// *--------------------------------------------------------------------------------*

#define N_IR_SENSORS 5

#define RESET_SENSOR {OUT_S1 = 0;OUT_S2 = 0;OUT_S3 = 0;OUT_S4 = 0;OUT_S5=0;}

unsigned int sensor_adc[N_IR_SENSORS];
unsigned int sensor_limit[N_IR_SENSORS];

void main()
{
unsigned char i;
unsigned char dataOut;
char calibrating = 1;


InitHW();
SPI_SS = 1;


LED=1;
DelayBigMs(400);
LED=0;
DelayBigMs(400);
LED=1;
DelayMs(20);

while(1)
{
if (calibrating)
{
readIRSensors(&sensor_limit);
for ( i = 0; i < N_IR_SENSORS;i++)
{
sensor_limit[i] = (sensor_limit[i] * 3 )/ 4;
}
calibrating= 0;
LED=0;
}
else
{
readIRSensors(&sensor_adc);

dataOut = 0;

for ( i = 0; i < N_IR_SENSORS;i++)
{
if (sensor_adc[i] < sensor_limit[i])
dataOut |= ( 1 << i);
}

if (IN_CS_SENSOR1 == 0) dataOut |= 0b01000000;
if (IN_CS_SENSOR2 == 0) dataOut |= 0b00100000;

if (dataOut != 0)
{
LED = 1;
dataOut |= 0b10000000; // b7 always is sent with 1
sendSPIData(dataOut);
DelayMs(50);
}
else
{
LED = 0;
}
}



}

}
//-----------------------------------------------------------------------------
// Read IR sensors
//-----------------------------------------------------------------------------

#define N_SAMPLES 4
void readIRSensors(unsigned int data[])
{
unsigned char nsample,idxIRSensor;

for (idxIRSensor = 0; idxIRSensor < N_IR_SENSORS; idxIRSensor++)
{
data[idxIRSensor] = 0;
}

for (nsample = 0; nsample < N_SAMPLES;nsample++)
{

 for (idxIRSensor = 0; idxIRSensor < N_IR_SENSORS; idxIRSensor++)
 {

RESET_SENSOR;
switch(idxIRSensor)
{
case 0:
OUT_S1 = 1;
ADCON0=0b00000001; // AN0 Go
break;
case 1:
OUT_S2 = 1;
ADCON0=0b00000101; // AN1 Go
break;
case 2:
OUT_S3 = 1;
ADCON0=0b00001001; // AN2 Go
break;
case 3:
OUT_S4 = 1;
ADCON0=0b00001101; // AN3 Go
break;
case 4:
OUT_S5 = 1;
ADCON0=0b00010001; // AN3 Go
break;

}

DelayMs(1);

ConvertADC();
while (BusyADC());
data[idxIRSensor] += ReadADC();

RESET_SENSOR;

 }
}

for (idxIRSensor = 0; idxIRSensor < N_IR_SENSORS; idxIRSensor++)
{
data[idxIRSensor] = data[idxIRSensor] / N_SAMPLES;
}

}
//-----------------------------------------------------------------------------
// Send SPI Data
//-----------------------------------------------------------------------------

const char mask[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void sendSPIData(unsigned char v)
{
signed char i;
SPI_SDO = 0;
SPI_SCK = 0;
DelayUs(100);
SPI_SS = 0;

for ( i = 7; i >= 0; i--)
{
SPI_SDO = (( v & mask[i]) > 0);
DelayUs(20);
SPI_SCK = 1;
DelayUs(50);
SPI_SCK = 0;
DelayUs(20);

}


SPI_SDO = 0;
SPI_SCK = 0;

SPI_SS = 1;

DelayUs(100);



}



// *--------------------------------------------------------------------------------*
« Última modificación: 30 de Enero de 2013, 20:07:44 por splasma2 »


 

anything