WEEK 11

Assignment :

Group Assignment : measure the analog levels and digital signals in an input device.

Individual Assignment : measure something: add a sensor to a microcontroller board that you have designed and read it.

Introduction





Our personality depends on our understanding about our surroundings .So our charactor, our skills everything depents on how accurately we know about our enviournment .So sensing is an important part in any logically decision making machine .A thermostat needs the ambient temperature reading to controll the heater or cooler in the room.An automatic street light need the external light intencity to turn on the light or turn it off.An internal combustion engine needs the crank position to injecting fuel or creating a timely spark , I need eyes to see wether the person reading this document is smiling or not .So literally everything we see arround having some ability to incorporate some logics in its actions are some way or another way using some kinds of sensors there may be exception but this is in most cases .

I am really excited to have this week. Today a piece of hardware is going to behave depending on my reaction. I am going to make a capacitive track wheel this week something similar to that we used in our old Ipods.So lets start!.



Some basics




Capacitive sensing may be used in any place where low to no force human touch sensing is desirable. An Arduino and the library may be used to sense human touch through more than a quarter of an inch of plastic, wood, ceramic or other insulating material (not any kind of metal though), enabling the sensor to be completely visually concealed. A capacitive sensor covered with paper or other insulator also acts as fairly good (human touch) pressure sensor with an approximately logarithmic response. In this regard it may surpass force sensing resistors in some applications



Noncontact capacitive sensors work by measuring changes in an electrical property called capacitance. Capacitance describes how two conductive objects with a space between them respond to a voltage difference applied to them. When a voltage is applied to the conductors, an electric field is created between them causing positive and negative charges to collect on each object. If the polarity of the voltage is reversed, the charges will also reverse.

For a capacitor



Where:
Vc is the voltage across the capacitor
Vs is the supply voltage
t is the elapsed time since the application of the supply voltage
RC is the time constant of the RC charging circuit

If Vc = Vs then t = T ,the equation will simplifies to

T= RxC

So for a capacitor with capacitance 'C' and series fixed resistance 'R' the time required to raise from 0V to Vs Volt is proportional to the capacitance .So if we cauld change the capacitance we can change raise time also .If we place our hand over the Sensor pad the effective capacitance of the circuit will increases there by increase the time required to raise the voltage from 0V to Vs volt(for us 5V)

The capacitiveSensor method toggles a microcontroller send pin to a new state and then waits for the receive pin to change to the same state as the send pin. A variable is incremented inside a while loop to time the receive pin's state change. The method then reports the variable's value, which is in arbitrary units.[arduino playground]

Designing PCB:-






I have tried some other sensors previously but i didn't tried capacitive sensing . So i decided to check wether my device will work befor designing a new PCB. I used an arduino mega to test a coustom capacitive sensor. You could have all the details of the library in this Arduino page.





Since my track wheel has some complicated geometries I decided to design my Cut profile and track wheel in Fusion 360 and import the DXF file in to eagle so that end result will be neat and clean.



I put some dummy pads in the places where I wanted to have my track wheels



Since I was short of I/O pins I choose MISO as the input for the capacitive sensor also.



I opened the exported PNG file in photoshop and filled the blank areas with black colour.



Soldering PCB:-






First is first. List all required components in a paper.



This is my board with components soldered.If you want to know about the PCB milling and soldering process please refer my week 5 page



It is always preferable to use some sort of dielectric material over the capacitive pading .Also for some sort of beautification also.



Programming:-



Remark!Programming the Atiny 44 was a greate challenge. The capacitive touch library I tried on Arduino Mega is not working properly in tiny 44.Also the program is too big to flash in to the atiny 44 memory.So i forced to think about an alternate way .When I gone through the arduino library file I found that the actual content I needed to excicute the program is very small compaired to the library .So i decided to implement that function in my own way .And this is the modified code



Arduino Code

#include <SoftwareSerial.h>
SoftwareSerial mySerial(1, 0); // RX, TX

#define SEND_PIN 5 //PORTA // ARDUINO 5

#define REC2_PIN 2 //PORTA // ARDUINO 2
#define REC1_PIN 3 //PORTA // ARDUINO 3
#define REC3_PIN 4 //PORTA // ARDUINO 4

#define LEDL_PIN 7 //PORTA // ARDUINO 7
#define LEDR_PIN 2 //PORTB // ARDUINO 8

int rec_pin_mean[5] = {0, 0, 12, 8, 10};
int rec_pin_value[5];
int rec_pin_pastv[5];
int calib_time = 0;

int count = 0;
int count_past = 0;
long led_ontime = 0;

int loopTimingFactor = 310;
int CS_Timeout_Millis = (2000 * (float)loopTimingFactor * (float)F_CPU) / 16000000;

void setup()
{
  mySerial.begin(9600);
  pinMode(SEND_PIN, OUTPUT);
  pinMode(REC1_PIN, INPUT);
  pinMode(REC2_PIN, INPUT);
  pinMode(REC3_PIN, INPUT);
  digitalWrite(SEND_PIN, LOW);

  DDRA |= (1 << LEDL_PIN);
  DDRB |= (1 << LEDR_PIN);
  PORTA |= (1 << LEDL_PIN);
  PORTB |= (1 << LEDR_PIN);
  delay(1000);
  PORTA &= ~(1 << LEDL_PIN);
  PORTB &= ~(1 << LEDR_PIN);
  calib_time = millis();
  calib();
}

void loop()
{
  calib();
  cs_read_value();
  rotation();
}


void rotation() {
  if ((rec_pin_value[REC1_PIN] != 0) || (rec_pin_value[REC2_PIN] != 0) ||  (rec_pin_value[REC3_PIN] != 0)) {
    if ((rec_pin_pastv[REC2_PIN] != rec_pin_value[REC2_PIN]) || (rec_pin_pastv[REC1_PIN] != rec_pin_value[REC1_PIN]) ||
         (rec_pin_pastv[REC3_PIN] != rec_pin_value[REC3_PIN])) {
      if (((rec_pin_pastv[REC1_PIN] == 1) && (rec_pin_value[REC2_PIN] == 1)) || ((rec_pin_pastv[REC2_PIN] == 1) &&
           (rec_pin_value[REC3_PIN] == 1)) || ((rec_pin_pastv[REC3_PIN] == 1) && (rec_pin_value[REC1_PIN] == 1))) {
        count++;
        PORTB |= (1 << LEDR_PIN);
        PORTA &= ~(1 << LEDL_PIN);
        led_ontime = millis();
        mySerial.println(count);
      }
      if (((rec_pin_pastv[REC3_PIN] == 1) && (rec_pin_value[REC2_PIN] == 1)) || ((rec_pin_pastv[REC2_PIN] == 1)
         && (rec_pin_value[REC1_PIN] == 1)) || ((rec_pin_pastv[REC1_PIN] == 1) && (rec_pin_value[REC3_PIN] == 1)))  {
        count--;
        PORTA |= (1 << LEDL_PIN);
        PORTB &= ~(1 << LEDR_PIN);
        led_ontime = millis();
        mySerial.println(count);
      }
    }
  }
}

void cs_read_value() {

  rec_pin_pastv[REC1_PIN] = rec_pin_value[REC1_PIN];
  rec_pin_pastv[REC2_PIN] = rec_pin_value[REC2_PIN];
  rec_pin_pastv[REC3_PIN] = rec_pin_value[REC3_PIN];
  rec_pin_value[REC1_PIN] = ((cs_mean(REC1_PIN) - rec_pin_mean[REC1_PIN]) > 3 ) ? 1 : 0;
  rec_pin_value[REC2_PIN] = ((cs_mean(REC2_PIN) - rec_pin_mean[REC2_PIN]) > 3 ) ? 1 : 0;
  rec_pin_value[REC3_PIN] = ((cs_mean(REC3_PIN) - rec_pin_mean[REC3_PIN]) > 3 ) ? 1 : 0;

}

void calib() {
  if ((millis() - calib_time) < 5000) {
    cs_calib(REC1_PIN);
    cs_calib(REC2_PIN);
    cs_calib(REC3_PIN);
    calib_time = millis();
  }
  if ((millis() - led_ontime) > 1000) {
    PORTA &= ~(1 << LEDL_PIN);
    PORTB &= ~(1 << LEDR_PIN);
  }
}

void cs_calib(uint8_t rec_pin) {
  if (abs(rec_pin_mean[rec_pin] - cs_read_cycle(rec_pin)) < 3) {
    cs_mean(rec_pin);
  }
}

int cs_mean(uint8_t rec_pin) {
  int mean = 0;
  for (uint8_t i = 0; i < 30; i++) {
    mean += cs_read_cycle(rec_pin);
  }
  return (mean / 30);
}

int cs_read_cycle(uint8_t rec_pin) {

  DDRA |= (1 << SEND_PIN);      // SEND PIN  OUTPUT
  PORTA &= ~(1 << SEND_PIN);   // SEND PIN  0
  DDRA |= (1 << rec_pin);     // REC  PIN  OUTPUT
  PORTA &= ~(1 << rec_pin);   // REC  PIN  0

  delayMicroseconds(10);

  DDRA &= ~(1 << rec_pin);    // REC  PIN  INPUT
  PORTA |= (1 << SEND_PIN);    // SEND PIN  1

  int cycles = CS_Timeout_Millis;
  for (int i = 0; i < cycles; i++) {
    if (PINA & (1 << rec_pin)) {
      cycles = i;
      break;
    }
  }
  PORTA |= (1 << rec_pin);
  DDRA |= (1 << rec_pin);
  PORTA |= (1 << rec_pin);
  DDRA &= ~(1 << rec_pin);
  PORTA &= ~(1 << SEND_PIN);
  return (cycles);
}



As the user rotae finger in clockwise direction on the trackwheel .The right LED will turn ON and the count will increase. If the user is rotaing in the anti clockwise direction then the left LED will turn ON and also decreases the count





EAGLE Schematics



Download File

Board PNG



Download File