ss
Dependencies: WS2812 PixelArray Adafruit_GFX
IRreflection.cpp
- Committer:
- eunsong
- Date:
- 2019-06-15
- Revision:
- 3:700a0cf6beea
- Parent:
- 0:27e31cadeb36
File content as of revision 3:700a0cf6beea:
#include "IRreflection.h"
// Base class data member initialization (called by derived class init())
TRSensors::TRSensors(PinName MOSI,PinName MISO, PinName CLK, PinName CS) : _spi(MOSI,MISO,CLK), _spi_cs(CS)
{
_spi.format(16,0);
_spi.frequency(2000000);
_spi_cs = 1;
_numSensors = NUMSENSORS;
}
void TRSensors::AnalogRead(int *sensor_values)
{
int i,j,ch;
int values[] = {0,0,0,0,0,0};
for(j = 0;j < _numSensors + 1;j++)
{
ch =j;
_spi_cs = 0;
wait_us(2);
values[j] = _spi.write(ch<<12);
_spi_cs = 1;
wait_us(21);
values[j] = (values[j]>>6);
}
for(i = 0;i < _numSensors;i++)
{
sensor_values[i] = values[i+1];
}
}
// Reads the sensors 10 times and uses the results for
// calibration. The sensor values are not returned; instead, the
// maximum and minimum values found over time are stored internally
// and used for the readCalibrated() method.
void TRSensors::calibrate_init(int *calibratedMin, int *calibratedMax)
{
for(int i=0;i<_numSensors;i++)
{
calibratedMin[i] = 1023;
calibratedMax[i] = 0;
}
}
void TRSensors::calibrate(int *sensor_values, int *calibratedMin, int *calibratedMax)
{
int i=0;
int j=0;
for(j=0;j<10;j++)
{
AnalogRead(sensor_values);
for(i=0;i<_numSensors;i++)
{
// set the max we found THIS time
if(j == 0 || max_sensor_values[i] < sensor_values[i])
max_sensor_values[i] = sensor_values[i];
// set the min we found THIS time
if(j == 0 || min_sensor_values[i] > sensor_values[i])
min_sensor_values[i] = sensor_values[i];
}
}
// record the min and max calibration values
for(i=0;i<_numSensors;i++)
{
if(min_sensor_values[i] > calibratedMax[i])
calibratedMax[i] = min_sensor_values[i];
if(max_sensor_values[i] < calibratedMin[i])
calibratedMin[i] = max_sensor_values[i];
}
}
// Returns values calibrated to a value between 0 and 1000, where
// 0 corresponds to the minimum value read by calibrate() and 1000
// corresponds to the maximum value. Calibration values are
// stored separately for each sensor, so that differences in the
// sensors are accounted for automatically.
void TRSensors::readCalibrated(int *sensor_values, int *calibratedMin, int *calibratedMax)
{
int i;
// read the needed values
AnalogRead(sensor_values);
for(i=0;i<_numSensors;i++)
{
int denominator;
denominator = calibratedMax[i] - calibratedMin[i];
int x = 0;
if(denominator != 0){
if(((signed int)sensor_values[i] - (signed int)calibratedMin[i])<0){
x = 0;}
else {
x = ((sensor_values[i] - calibratedMin[i])*1000/denominator);
}
}
if( x > 1000) x = 1000;
sensor_values[i] = x;
}
}
// Operates the same as read calibrated, but also returns an
// estimated position of the robot with respect to a line. The
// estimate is made using a weighted average of the sensor indices
// multiplied by 1000, so that a return value of 0 indicates that
// the line is directly below sensor 0, a return value of 1000
// indicates that the line is directly below sensor 1, 2000
// indicates that it's below sensor 2000, etc. Intermediate
// values indicate that the line is between two sensors. The
// formula is:
//
// 0*value0 + 1000*value1 + 2000*value2 + ...
// --------------------------------------------
// value0 + value1 + value2 + ...
//
// By default, this function assumes a dark line (high values)
// surrounded by white (low values). If your line is light on
// black, set the optional second argument white_line to true. In
// this case, each sensor value will be replaced by (1000-value)
// before the averaging.
int TRSensors::readLine(int *sensor_values , int *calibratedMin, int *calibratedMax, int *online, char white_line)
{
char i, on_line = 0;
long int avg; // this is for the weighted total, which is long
// before division
int sum; // this is for the denominator which is <= 64000
static int last_value=0; // assume initially that the line is left.
readCalibrated(sensor_values, calibratedMin, calibratedMax);
online[0] = 0;
avg = 0;
sum = 0;
for(i=0;i<_numSensors;i++) {
long int value = sensor_values[i];
//if(!white_line) value = 1000-value;
if(white_line){
value = 1000-value;
//sensor_values[i] = (1000 - sensor_values[i])/100;
}
//sensor_values[i] = value;
// keep track of whether we see the line at all
if(value > 300) {
online[0] = 1;
}
// only average in values that are above a noise threshold
if(value > 30) {
avg += value*(1000*i);//(value/100)*(1000*i) // * sqrt(100,i);
sum += value; //(value/100);
}
}
/*
if(!on_line)
{
// If it last read to the left of center, return 0.
if(last_value < (_numSensors-1)*1000/2)
return 0;
// If it last read to the right of center, return the max.
else
return (_numSensors-1)*1000;
}
*/
last_value = avg/sum;
// if(sum == 0) last_value = 0;
return last_value;
}
int TRSensors::sqrt(int m, int k){
int temp = m;
if(k == 0) m = 1;
else{
for(int i=0; i<(k-1); i++){
m = temp *m;
}
}
return m;
}