Featured image of post week11

week11

Inputs Devices

Group assignment:

  • Probe an input device(s)’s analog and digital signals
  • Document your work on the group work page and reflect on your individual page what you learned
  • Individual assignment:
  • Measure something: add a sensor to a microcontroller board that you have designed and read it.

Learning outcomes

  • Demonstrate workflows used in sensing something with input device(s) and MCU board

Have you answered these questions?

  • Linked to the group assignment page.
  • Documented what you learned from interfacing an input device(s) to your microcontroller and how the physical property relates to the measured results.
  • Documented your design and fabrication process or linked to the board you made in a previous assignment.
  • Explained the programming process/es you used.
  • Explained any problems you encountered and how you fixed them.
  • Included original design files and source code.
  • Included a ‘hero shot’ of your board.

Recitation: https://vimeo.com/817105164

Review: https://vimeo.com/819315220

Slides: http://academy.cba.mit.edu/classes/input_devices/index.html

Probe sensor signals

Potentiometer

Potentiometer, probe on middle pad, ground and 5V on other pads:

Joystick

Now signal from a analog joystick, one probe on x axis, the other on y. Those joystick are simply one potentiometer for x axis, another for y axis and a button for click detection.

Time Of Flight sensor

I connect a VL53V0X time of flight sensor to an arduino uno through i2c (SDA and SCL pins). Then I simply print the distance to serial and display it in realtime with the serial plotter tool of the Arduino IDE.

Step response as touch sensor

I cut and connect 2 copper adhesive to an oscilloscope following Robert Hart’s tutorial and Neil’s examples. Instead of using a microcontroler to read the signal I do it with an oscilloscope on one of the tape and connect a signal generator on the other one. The generator output a square signal with 5V amplitude and 100Mhz frequency.

image

Step response as liquid volume detector

Now, with the setup signal generator and oscilloscope setup, I place the 2 electrodes on a syringe and check the signal when filling and unfilling it with water.

image

Multiple area touch sensor

For my final project, I would like to include a step reponse sensor array to detect simple gesture as wiping left/right and rotation, covering the whole surface of my pcb.

Code

The code for step response sensor is based on this one:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//tx_rx03  Robert Hart Mar 2019.
//  Program to use transmit-receive across space between two conductors.
//  One conductor attached to digital pin, another to analog pin.
//
//  This program has a function "tx_rx() which returns the value in a long integer.
//
//  Optionally, two resistors (1 MOhm or greater) can be placed between 5V and GND, with
//  the signal connected between them so that the steady-state voltage is 2.5 Volts.
//
//  Signal varies with electric field coupling between conductors, and can
//  be used to measure many things related to position, overlap, and intervening material
//  between the two conductors.
//
long result;   //variable for the result of the tx_rx measurement.
int analog_pin = A3;
int tx_pin = A1;

void setup() {
    pinMode(tx_pin,OUTPUT);      //Pin 4 provides the voltage step
    Serial.begin(9600);
}

long tx_rx(){         //Function to execute rx_tx algorithm and return a value
                      //that depends on coupling of two electrodes.
                      //Value returned is a long integer.
  int read_high;
  int read_low;
  int diff;
  long int sum;
  int N_samples = 100;    //Number of samples to take.  Larger number slows it down, but reduces scatter.

  sum = 0;

  for (int i = 0; i < N_samples; i++){
   digitalWrite(tx_pin,HIGH);              //Step the voltage high on conductor 1.
   read_high = analogRead(analog_pin);        //Measure response of conductor 2.
   delayMicroseconds(100);            //Delay to reach steady state.
   digitalWrite(tx_pin,LOW);               //Step the voltage to zero on conductor 1.
   read_low = analogRead(analog_pin);         //Measure response of conductor 2.
   diff = read_high - read_low;       //desired answer is the difference between high and low.
 sum += diff;                       //Sums up N_samples of these measurements.
 }
  return sum;
}                         //End of tx_rx function.


void loop() {

result = tx_rx();
Serial.println(result);
//delay(100);
}

Sensor design

To do so, I design a layer of copper with multiple areas and holes to let the LEDs light pass through. I design this layer into Fusion 360.

image

1 2
image image

I then export a 2D view as a DXF file. To do so, right click on the sketch use to create the 3D model and “export as dxf” or right click>Create drawing" then project the top face at 1:1 scale and export as pdf.

I made 2 trials, one with the vinyl cutter on copper tape and another by engraving and cutting a blank pcb board.

First, I test the setup on breadboard

image

Then I soldered some pins header on the capacitive layer to connect it to my final project PCB.

image

Capacitive layer solder to my final project pcb, on top of the leds.

image

Schematic of the 4 input and 1 output connected to the microcontroler. J1 to J4 are holes intendeed to connect the sensor layer with male pinheaders.

image

Connection pads for sensor layer image

1 2 3
image image image

Schematics and PCB can be found here:

Kicad schematics Kicad PCB

Reading sensors values

Here is the code related to sensors reading. I adapted tx_rx() code to read all values in one call

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#define CAP_INPUT_1 D3// D3 is ADC2, CONFLICTING WITH WIFI
#define CAP_INPUT_2 D1
#define CAP_INPUT_3 D2
#define CAP_INPUT_4 D0
#define CAP_OUTPUT  D4

long int cap_array_values[4] = {0,0,0,0};

void setup() {
  pinMode(CAP_OUTPUT,OUTPUT);
}

void loop(){

    tx_rx_all_channels(sum); //we pass sum (array adress), it will be modified inside method

    for(int i=0;i<4;i++){
        Serial.print(cap_array_values[i]);
        if(i!=3)Serial.print(",");
    }
    Serial.println();
}

void tx_rx_all_channels(long int* sum){        
  //Function to execute rx_tx algorithm and return a value
  //that depends on coupling of two electrodes.
  //Value returned is a long integer.
  int read_high[4];
  int read_low[4];
  int diff[4];

  int pin_ids[4] = {CAP_INPUT_1,CAP_INPUT_2,CAP_INPUT_3,CAP_INPUT_4};
  int N_samples = 100;    //Number of samples to take.  Larger number slows it down, but reduces scatter.

  for(int i=0;i<4;i++) sum[i] = 0; //Reset
  

  for (int i = 0; i < N_samples; i++){

    digitalWrite(CAP_OUTPUT,HIGH);      //Step the voltage high on conductor 1.

    read_high[0] = analogRead(pin_ids[0]);
    read_high[1] = analogRead(pin_ids[1]);
    read_high[2] = analogRead(pin_ids[2]);
    read_high[3] = analogRead(pin_ids[3]);

    delayMicroseconds(100);            //Delay to reach steady state.
    digitalWrite(CAP_OUTPUT,LOW);      //Step the voltage to zero on conductor 1.

    read_low[0] = analogRead(pin_ids[0]);
    read_low[1] = analogRead(pin_ids[1]);
    read_low[2] = analogRead(pin_ids[2]);
    read_low[3] = analogRead(pin_ids[3]);

    //desired answer is the difference between high and low.
    for(int j=0;j<4;j++){diff[j] = read_high[j] - read_low[j];}
    
    //Sums up N_samples of these measurements.
    for(int j=0;j<4;j++){sum[j] += diff[j];} 
                        
  }
}   

Coding and upload problem

During development, I upload a faulty code using pointers in my arduino code. It ended up by blocking the device (reseting constantly) and I wasn’t able to upload anymore. image

I was ready to use a new esp board, hopefully, I follow a trick from this page that unlock the situation.

1
2
3
4
5
6
- Create an empty sketch with a debug line in the loop. Something like Serial.println("debug line");. I tried to upload this code and connect via SERIAL to see if it was uploaded correctly.
- Upload the code directly from esptool.py. As I program it from the arduino ide, the easiest way is to activate the upload debug in the ide. File > preferences> "Show detailed output while" > "Upload".
- Upload the sketch from the debug line. It will generate the error "A fatal error occurred: Unable to verify flash chip connection (No serial data received.)." But at the top of the arduino IDE console the executed esptool.py command will appear. Something like this:  
    `Las variables Globales usan 48428 bytes (14%) de la memoria dinámica, dejando 279252 bytes para las variables locales. El máximo es 327680 bytes. C:\Users\user\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.5.1/esptool.exe --chip esp32s3 --port COM3 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 8MB 0x0 C:\Users\user\AppData\Local\Temp\arduino_build_393730/MySketch.ino.bootloader.bin 0x8000 C:\Users\user\AppData\Local\Temp\arduino_build_393730/MySketch.ino.partitions.bin 0xe000 C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.9/tools/partitions/boot_app0.bin 0x10000 C:\Users\user\AppData\Local\Temp\arduino_build_393730/MySketch.ino.bin esptool.py v4.5.1 Serial port COM3`
- Copy the command and run it, adding the **--no-stub** parameter at the begining. This will allow to upload the new sketch. With this you can upload sketches from the arduino IDE again. In my case was:  
    `C:\Users\user\AppData\Local\Arduino15\packages\esp32\tools\esptool_py\4.5.1/esptool.exe --no-stub --chip esp32s3 --port COM3 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 8MB 0x0 C:\Users\user\AppData\Local\Temp\arduino_build_393730/MySketch.ino.bootloader.bin 0x8000 C:\Users\user\AppData\Local\Temp\arduino_build_393730/MySketch.ino.partitions.bin 0xe000 C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.9/tools/partitions/boot_app0.bin 0x10000 C:\Users\user\AppData\Local\Temp\arduino_build_393730/MySketch.ino.bin`

Problem with ADC_2

It seems that D4 pin is not usable when wifi is enabled, it will be a problem when I will use it for my final project. Furthermore, I got a warning about using it in the serial output.

image

Sensing with/without plexiglass lens

Without plexiglass

Sensing without the lens works fine and can easily trigger some action…

For better visualisation, I switch on some LEDs depending of touch area.

With plexiglass

It will be far more delicate with this additional layer on the sensor. It is problably due to electrode size that have too little copper area. To obtain something usable, I will have to forget my matrix sensor, and make only a 1 emitor / 1 receiver configuration.

image

The signal is weak and very noisy. I try to improve it by averaging the signal using the code bellow, where epsilon is a coefficient beetween 0 to 1 defining the update rate. For example, epsilon = 1 mean that the average value is only the current value, epsilon = 0.5 mean that half of the average value is due to the new value.

1
2
3
4
5
6
7
8
float smoothed_value =0.;

void loop(){
    [...]
    new_value = analogRead(SENSOR_PIN);
    smoothed_value = (1 - epsilon)*smoothed_value + epsilon*new_value;
    [...]
}

Unfortunatly, even whith smoothing, the signal on press is not easily distinguishable. I will investigate later if i found some time…

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy