Input Devices

Measure something


PCB design

For some weeks I have been designing control board for my final project. The control board has three sensors: line sensors (1), sonar sensor (2) and battery level sensor (3).

You can download Control Board Cut File here and Traces File here.

Line sensors are based on five phototransistors illuminated by blue leds.

You can download Line Sensors Board Cut File here and Traces File here.

Connect line sensors and sonar sensor.


Programming Microcontroller

Line Sensors are measured with ADC inputs of microcontroller.

// reset sensors vector
for(unsigned char j=0; j<5; j++)
	sensors[j] = 0;

// measure 64 times all sensors
for(unsigned char i=0; i<64; i++){
	sensors[0] += analogRead(A3);  
	sensors[1] += analogRead(A2);
	sensors[2] += analogRead(A1);
	sensors[3] += analogRead(A0);
	sensors[4] += analogRead(A7);
}

// divide each sensor for 64
for(unsigned char j=0; j<5; j++)
	sensors[j] = sensors[j] >> 6;
			
			

Sonar Sensor is measured with one timer of microcontroller.

unsigned int distance(long timeout) {
	// pulse trigger pin
	digitalWrite(TG, LOW);
	delayMicroseconds(4);
	digitalWrite(TG, HIGH);
	delayMicroseconds(10);
	digitalWrite(TG, LOW);
	
	// measure echo pulse time
	long _t = pulseIn(EC, HIGH, timeout);
	if(_t == 0)
		_t = timeout;
	
	// return distance in mm
	return uint16_t(_t*10/29/2);  
}
			
			

Battery level sensor is measured with ADC inputs of microcontroller becouse this sensor consist in a voltage divider. In this board I use a 10 Kohm resistor serially with a 4.99 Kohm resistor, therefore the input voltage is divided for 3.

unsigned int level(int channel){
	long v = analogRead(channel);
	v = v*15000/1023;

	return uint16_t(v);
}
			
			

The complete code consist in measure the three sensors and send its values trough the serial port.

unsigned long sensors[5];
unsigned char samples = 64;

#define TG 3
#define EC 4

unsigned int distance(long timeout) {
	digitalWrite(TG, LOW);
	delayMicroseconds(4);
	digitalWrite(TG, HIGH);
	delayMicroseconds(10);
	digitalWrite(TG, LOW);
	long _t = pulseIn(EC, HIGH, timeout);
	if(_t == 0)
		_t = timeout;

	return uint16_t(_t*10/29/2);  
}

unsigned int level(int channel){
	long v = analogRead(channel);
	v = v*15000/1023;

	return uint16_t(v);
}

void setup() {
	Serial.begin(115200);
	pinMode(TG, OUTPUT);
	pinMode(EC, INPUT);
}

void loop() {
	for(unsigned char j=0; j<5; j++)
		sensors[j] = 0;

	for(unsigned char i=0; i<samples; i++){
		sensors[0] += analogRead(A3);  
		sensors[1] += analogRead(A2);
		sensors[2] += analogRead(A1);
		sensors[3] += analogRead(A0);
		sensors[4] += analogRead(A7);
	}
	  
	for(unsigned char j=0; j<5; j++)
		sensors[j] = sensors[j] >> 6;

	for(unsigned char j=0; j<5; j++){
		Serial.print(sensors[j]);
		Serial.print(" ");
	}    

	Serial.print(distance(6000));
	Serial.print(" ");

	Serial.print(level(A6));
	Serial.print(" ");

	Serial.println();

	delay(60);
}
			
			

Programming Interface

I programming the Interface in Processing.

import processing.serial.*;

Serial serial;

PFont f1, f2, f3;

int[] lineSensors = new int[5];
int sonarSensor;
// vector for store 400 values of battery level sensor and can draw the wave
int[] levelSensor = new int[401];
int _i_level = 0;

void setup(){
	size(600, 400);

	println(Serial.list());
	// Serial.list()[#] -> # is the port number where is connected the ftdi
	serial = new Serial(this, Serial.list()[0], 115200);

	f1 = createFont("Arial", 18, true);
	f2 = createFont("ACaslonPro-BoldItalic", 14, true);
	f3 = createFont("Arial", 12, true);
}

void draw(){
	// wait to receive data from control board
	updateSerial();

	// reset bacground
	background(245);
	
	// Title
	textFont(f1, 18);
	fill(0);
	textAlign(CENTER);
	text("INPUT DEVICES", width/2, 22);

	stroke(175);
	line(0, 30, width, 30);
	
	textFont(f2, 14);
	fill(75);
	textAlign(CENTER);
	text("Line Sensors", width/4, 55);
	
	// Draw Line sensors
	for(int j=0; j<5; j++){
		fill(0);
		rect(75+(j<<5), 70, 20, 1023>>3);
		fill(255);
		rect(75+(j<<5), 70, 20, lineSensors[j]>>3);
	}

	stroke(175);
	line(width/2, 30, width/2, 220);

	textFont(f2, 14);
	fill(75);
	textAlign(CENTER);
	text("Sonar Sensor", 3*width/4, 55);

	// Draw Sonar sensor
	fill(255);
	rect(350, 120, 200, 40);
	fill(0);
	rect(350, 120, sonarSensor*200/1034, 40);
	int d = sonarSensor/10;
	textFont(f3, 12);
	fill(75);
	textAlign(CENTER);
	text(d + " cm", 350 + (sonarSensor*200/1034), 110);

	stroke(175);
	line(0, 220, width, 220);

	textFont(f2, 14);
	fill(75);
	textAlign(CENTER);
	text("Battery Level Sensor", width/2, 245);
	
	// Draw Battery level sensor
	fill(255);
	rect(39, 260, 402, 122);
	noStroke();
	for(int i=1; i<=_i_level; i++){
		if(levelSensor[i]>12500 || levelSensor[i]<7500) fill(255,0,0);
		else fill(0);
		ellipse(40+i, 261+((15000-levelSensor[i])/125),1,1);
	}
	textFont(f1, 18);
	if(levelSensor[_i_level]>12500 || levelSensor[_i_level]<7500) fill(255,0,0);
	else fill(0);
	textAlign(CENTER);
	text(levelSensor[_i_level] + " mV", 520, 325);
}

void updateSerial(){
	String data = serial.readStringUntil('\n');
	if(data != null){
		//println(data);
		String[] values = split(data, " ");
		if(values.length == 8){
			for(char i=0; i<5; i++)
			lineSensors[i] = int(values[i]);
			sonarSensor = int(values[5]);
			if(_i_level<400){
				_i_level++;
				levelSensor[_i_level] = int(values[6]);
			}
			else{
				for(int i=1; i<400; i++)
				levelSensor[i] = levelSensor[i+1];
				levelSensor[400] = int(values[6]);
			}
		}
	}
}