Assignment | Used software | Files/Downloads/links |
---|---|---|
Code for the final project | Arduino-IDE | gauge_meter_oled_final.ino |
Code for my final project Fabacademy 2018
In words
This is how this code works till now.
- When the device is powered, it will start the loop.
-
first it checks if the battery is being charged at the moment.
- if it is being charged it starts displaying the gaugemeter on the oled display
-
if it not, it continuously reads the values coming in from the piezos connected to gate A0 and A1
- if it is above the threshold (100) it clears the display
- the value coming in from piezo1 is printed on top and that of piezo 2 on the 2nd line
- after this point is starts over again (loop)
I commented the code below to specify all functions and variables.
This is what this code does now. Still have to include peak detection, measuring time between peaks from the 2 piezo’s and calculate the thickness of the ice. It will be something like this:
When piezo 1, connected to A0, is triggered and a analogRead on A0 receives the value 1023 (highest value), it will do peak detection to get the first peak after the initial hit. This peak is the first reflection from the underlayer of the ice. When detected this peak, it will start counting the time with milis(). Piezo 2 connected to A1, will do the same peak detection. When it receives the first peak, milis will have a value of in miliseconds. After calibrating (i need ice for that :) i can calculate the value of the miliseconds into the thickness of ice.
This is the code that i use now for my final project:
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
int xmax=128;
int ymax=62;
int xcenter=xmax/2;
int ycenter=ymax/2+10;
int arc=ymax/2;
int angle=0;
char* label[] = {"LOAD","COOLANT","INTAKE", "VOLT"};
int labelXpos[] = {53, 45, 49, 53};
int p, w, m,a=10;
u8g_uint_t xx=0;
The code starts with the data-types for number storage of the U8glib that drives the oled display. It devines the specific oled board and gives the dimension of the display that are going to be used to draw the gauagemeter, including the label and its position.
int chargePin = PD2;
The gate of the chargePin, the gate connected to the LED external pin of the Solar LiPo Charge board.
// Piezo part
// these constants won't change:
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int knockSensor1 = A1;// the piezo is connected to analog pin 1
const int threshold = 100; // threshold value to decide when the detected sound is a knock or not
// these variables will change:
int sensorReading = 0; // variable to store the value read from the sensor pin 0
int sensorReading1 = 0; // variable to store the value read from the sensor pin 1
The data-types for the piezos, connected to A0 and A1, setting the threshold to 100 and define the value for the piezo output (sensorReading(1)) to 0.
#include <Wire.h>
#include <LiFuelGauge.h>
void lowPower();
// LiFuelGauge constructor parameters
// 1. IC type, MAX17043 or MAX17044
// 2. Number of interrupt to which the alert pin is associated (Optional)
// 3. ISR to call when an alert interrupt is generated (Optional)
//
// Creates a LiFuelGauge instance for the MAX17043 IC
// and attaches lowPower to INT0 (PIN2 on most boards, PIN3 on Leonardo)
LiFuelGauge gauge(MAX17043, 3, lowPower);
// A flag to indicate a generated alert interrupt
volatile boolean alert = false;
The data-types for the LiFuelGauge, using the wire and the LiFuelGauge library. Setting the specific board (MAX17043), the numer of interrupts and the called Interrupt Service Routine - lowpower, specified at the end of the code (void lowPower() { alert = true; })
#define u8g_logo_width 128
#define u8g_logo_height 64
static unsigned char u8g_logo_bits[] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x80, 0x1f, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x1e, 0x0f,
0x80, 0x3b, 0x0f, 0x0f, 0x8f, 0x19, 0x9f, 0x1b, 0x8f, 0x8d, 0x1f, 0x0f,
0x00, 0x06, 0x9f, 0x1f, 0x80, 0xbf, 0x9f, 0x9f, 0x9f, 0x19, 0xbf, 0xbf,
0x9f, 0x9f, 0x9f, 0x1f, 0x00, 0x86, 0x81, 0x31, 0x80, 0xb6, 0x31, 0x9e,
0x81, 0x19, 0x83, 0xb6, 0xb1, 0x19, 0x86, 0x01, 0x00, 0x86, 0x81, 0x3f,
0x80, 0xb6, 0xbf, 0x3f, 0x87, 0x19, 0x83, 0xb6, 0xbf, 0x19, 0x06, 0x07,
0x00, 0x86, 0x81, 0x3f, 0x80, 0xb0, 0xbf, 0x31, 0x9c, 0x19, 0x83, 0xb6,
0xbf, 0x19, 0x06, 0x1c, 0x00, 0x86, 0x81, 0x01, 0x80, 0xb0, 0x81, 0x39,
0x98, 0x19, 0x83, 0xb6, 0x81, 0x19, 0x06, 0x18, 0x80, 0x1f, 0x9f, 0x1f,
0x80, 0xb0, 0x9f, 0xbf, 0x9f, 0x1f, 0x83, 0xb6, 0x9f, 0x19, 0x9e, 0x1f,
0x80, 0x1f, 0x1e, 0x1f, 0x80, 0x30, 0x1f, 0x37, 0x0f, 0x1f, 0x83, 0x36,
0x9f, 0x19, 0x1c, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x19, 0x0f, 0x0f, 0x8f, 0x87, 0x0d,
0x37, 0x80, 0x19, 0x8f, 0xb1, 0x07, 0x1e, 0x0f, 0x80, 0x81, 0x99, 0x9f,
0x9f, 0x1f, 0x87, 0x9f, 0x3f, 0x80, 0xb1, 0x9f, 0x19, 0x07, 0x9f, 0x1f,
0x80, 0x99, 0x99, 0xb1, 0x81, 0x01, 0x86, 0x99, 0x39, 0x80, 0xb1, 0xb1,
0x19, 0x86, 0x81, 0x31, 0x80, 0xb9, 0x99, 0x3f, 0x07, 0x07, 0x86, 0x99,
0x39, 0x80, 0xb1, 0x3f, 0x19, 0x86, 0x81, 0x3f, 0x80, 0xb1, 0x99, 0x3f,
0x1c, 0x1c, 0x86, 0x99, 0x39, 0x80, 0xb1, 0x3f, 0x1b, 0x86, 0x81, 0x3f,
0x80, 0xb3, 0x99, 0x01, 0x18, 0x18, 0x86, 0x99, 0x39, 0x80, 0x99, 0x01,
0x0f, 0x86, 0x81, 0x01, 0x00, 0xbf, 0x9f, 0x9f, 0x9f, 0x1f, 0x9e, 0x99,
0x3f, 0x80, 0x9f, 0x1f, 0x0e, 0x1e, 0x9f, 0x1f, 0x00, 0x1e, 0x1f, 0x1f,
0x0f, 0x0f, 0xbc, 0x19, 0x1f, 0x80, 0x0f, 0x1f, 0x0e, 0x3c, 0x1e, 0x1f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
This is the splah display. I made it with gimp, saving a bitmap as xbm.
void gauge1(uint8_t angle) {
// draw border of the gauge
u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT);
u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT);
u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT);
u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT);
// draw the needle
float x1=sin(2*angle*2*3.14/360);
float y1=cos(2*angle*2*3.14/360);
u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);
u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT);
u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT);
u8g.setFont(u8g_font_chikita);
// show scale labels
u8g.drawStr( 20, 42, "0");
u8g.drawStr( 25, 18, "25");
u8g.drawStr( 60, 14, "50");
u8g.drawStr( 95, 18, "75");
u8g.drawStr( 105, 42, "100");
// show gauge label
u8g.setPrintPos(labelXpos[0],32);
u8g.print(label[0]);
// show digital value and align its position
u8g.setFont(u8g_font_profont22);
u8g.setPrintPos(54,60);
if (w<10){
u8g.print("0");
}
if (w>99) {
u8g.setPrintPos(47,60);
}
u8g.print(w);
}
This is the function that first draws the border of the gaugemeter, draws the needle and showing the labels.
Now the setup loop starts:
void setup(void) {
u8g.setFont(u8g_font_chikita);
u8g.setColorIndex(1);
// assign default color value
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255);
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3);
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1);
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
Serial.begin(9600); // Initializes serial port
// Waits for serial port to connect. Needed for Leonardo only
//while ( !Serial ) ;
gauge.reset(); // Resets MAX17043
delay(200); // Waits for the initial measurements to be made
pinMode(chargePin, INPUT_PULLUP);
// Sets the Alert Threshold to 10% of full capacity
gauge.setAlertThreshold(10);
Serial.println(String("Alert Threshold is set to ") +
gauge.getAlertThreshold() + '%');
}
In the setup the fornts for the oled are defined, the colorvalue is set, serial is setup. Also the gaugemeter is reset and the alert for the battery is set to 10%. Also the pinmode for the chargePin is set to INIT_PULLUP to see if the device is being charged.
void loop(void) {
if (digitalRead(chargePin) == LOW )
{
chargeBatt();
}
else {
// the splash screen starts here, but i disabled it temporary
//
// u8g.firstPage();
// do {
// u8g.drawXBMP( 0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);
// } while( u8g.nextPage() );
//
// clearOLED();
sensorReading = analogRead(knockSensor);
sensorReading1 = analogRead(knockSensor1);
if (sensorReading >= threshold) {
clearOLED();
u8g.firstPage();
do {
u8g.setFont(u8g_font_gdr25r);
//u8g.drawStr(8, 30, "Eeee");
char buf[9];
sprintf (buf, "%d", sensorReading);
u8g.drawStr(18, 32, buf);
//char buf[9];
sprintf (buf, "%d", sensorReading1);
u8g.drawStr(18, 62, buf);
}
while( u8g.nextPage() );
// delay(200);
}
}
}
The loop is actually really short. If the chargePin is LOW (meaning charging the device), it calls the function chargeBatt defined later in the code.
Else it reads the values of both piezo’s, clears the oled display and draws the measurements of the piezos.
void chargeBatt() {
// p = analogRead(D2);
p = (gauge.getSOC())*10.24-120;
w = map(p,0,1023,0,100);
m = map(p,0,1023,0,90);
// show needle and dial
xx = m;
if (xx<45){
xx=xx+135;
}
else {
xx=xx-45;
}
// picture loop
{
u8g.firstPage();
do {
gauge1(xx);
}
while( u8g.nextPage() );
}
Serial.print("SOC: ");
Serial.print(gauge.getSOC()); // Gets the battery's state of charge
Serial.print("%, VCELL: ");
Serial.print(gauge.getVoltage()); // Gets the battery voltage
Serial.println('V');
if ( alert )
{
Serial.println("Beware, Low Power!");
Serial.println("Finalizing operations...");
gauge.clearAlertInterrupt(); // Resets the ALRT pin
alert = false;
Serial.println("Storing data...");
Serial.println("Sending notification...");
Serial.println("System operations are halted...");
gauge.sleep(); // Forces the MAX17043 into sleep mode
while ( true )
float cos = (gauge.getSOC());
float cis = (gauge.getVoltage());
}
}
This is the chargeBatt function that is called when the battery is being charged. It reads the gauge.getSOC, the State Of Charge (SOC) of the battery and draws as needle and number at the oled display. It also prints the values to serial for reading on a computer when it is connected through FTDI. If alert (less than 10% SOC, it prints a message to serial, send an alerts (when the pin is connected to my atmega - see at the end of this page) and forces the MAX17043 into sleep mode.
void clearOLED(){
u8g.firstPage();
do {
} while( u8g.nextPage() );
}
A function to clear the oled display from previous draws.
void lowPower() { alert = true; }
The stat of the lowPower (alert is on but not activated). If alert is false, battery SOC =<10% is should put the atmega board in sleep modus.
Working on high peak detection and timing
After the presentation i started working on high peak detection and timing. The idea is that after the initial hit (hammering):
- starts detecting the first peak on the first piezo
- starting to count in milliseconds [(millis)](https://www.arduino.cc/reference/en/language/functions/time/millis/)
- detects the high peak on the second piezo
- stops counting in milliseconds
- calculates the thickness of ice
I’m still not that far. But here is the code so far. As said, it is not ready yet. Parts of the code i took from the arduino forum. I modified it for my board. High peak measurement is done in a function called AnalogMaxima (at the end). It read the values of the piezo over and over again. If the current value is higher than the last value it keeps on reading new values from the piezo. Once it get a lower value the last value is set and gives the Hit back to the loop. It starts counting in milliseconds and starts reading the signals coming in at the second piezo. Also here it starts detecting the high peak. Once it has the high peak, it stops counting in milliseconds.
The code still doesn’t do what i want. I have to put more time into it, doing research and a lot of trial and error to get better results. What i also have to do is measuring the high peaks with the oscilloscope to compare it with the values and timing i get from my board.
I hope to find some time around Fab14 and complete this code.
const int knockSensor = A1;
const int knockSensor1 = A0;
int Threshold = 200;
int velocity;
int Hit;
int Hit1;
int check1;
long previousMillis = 0; // variable to store last time LED was updated
long startTime ; // start time for stop watch
long elapsedTime ; // elapsed time for stop watch
int fractional; // variable used to store fractional part of time
void setup(void) {
Serial.begin(38400);
}
void loop(){
for (int i = 0;i<=5;i++) {
if(analogRead(knockSensor)>Threshold){ //If current channel reading exceeds threshold
Hit = AnalogMaxima (knockSensor,Threshold,2); //find local maxima and return value.
if (Hit == 1025|| Hit == 0){ //if still ascending or below threshold,
break; //go to next piezo.
}
}
else{
startTime = millis();
if (analogRead(knockSensor1)>Threshold){ //If current channel reading exceeds threshold
Hit = AnalogMaxima (knockSensor1,Threshold,2); //find local maxima and return value.
if (Hit1 == 1025 || Hit == 0){ //if still ascending or below threshold,
// break;
Serial.println(Hit);
elapsedTime = millis() - startTime;
Serial.println(check1);
Serial.print( (int)(elapsedTime));
Serial.println("in miliseconds");
delay(2000);
}
}
}
}
}
/* AnalogMaxima compares succesive readings from ADC on channel AnalogCh
and returns :
1025 if voltage is decreasing,so that only the maxima is returned.
0 if below threshold.
or returns the highest value when voltage starts to drop (local maxima).
AnalogCh : Channel on the ADC to check for maxima.
Threshold : Lowest voltage reading to begin maxima evaluation.
Delay : Delay between sucknockSensorcesive readings.
*/
int AnalogMaxima (int AnalogCh, int Threshold, int Delay){
int check1; //variable to store first reading.
int check2; //variable to store second reading.
check1 = analogRead(knockSensor); //Assing first reading
delay(Delay); //wait
check2 = analogRead (knockSensor); //Assing second reading.
if (check1>check2){ //If voltage is DECREASING (no maxima)...
return 1025; //end loop and return 1025.
}
else{
while (analogRead(knockSensor)>Threshold){ //While above threshold and RISING
check1 = analogRead(knockSensor); //Assing first reading
delay(Delay/2); //wait
check2 = analogRead (knockSensor); //Assing second reading.
delay(Delay/2); //wait,and loop unless...
if (check1>check2){ //voltage drop is observed
return check1; //if so return highest value :)
}
}
}
} // end of AnalogMaxima //
Code that i don’t use right now but gathered for possible intergration
Switch: initial start
I am not using this code, but keep it on the page for eventually later use…
/*Final Project Fabacademy 2018 - input_pullup button/activator used for
* Ice Thickness Measuring Device
* http://archive.fabacademy.org/2018/labs/fablabamsterdam/students/henk-buursen/index.html
*
*
*/
const int switchPin = 4; //Switch Connected to PIN 4
const int ledPin = 3; //LED Connected to PIN 13
int switchState = 0; //Variable for reading switch status
void setup()
{
pinMode(ledPin, OUTPUT); //LED PIN is Output
pinMode(switchPin, INPUT_PULLUP); //Switch PIN is Input
}
void loop()
{
switchState = digitalRead(switchPin); //Read the status of the Switch
if (switchState == LOW) //If the switch is pressed
{
digitalWrite(ledPin, LOW); //LED ON
delay(500); //0.5 Second Delay
digitalWrite(ledPin, HIGH); //LED OFF
}
}
Piezos: impulse measuring
First i try to measure the impulses. Piezo’s on wood, pushed a bit with silicon on top.
I use this code:
const int knockSensor0 = A0;
const int knockSensor1 = A1; // the piezo is connected to analog pin 0
const int Threshold1 = 100; // threshold value to decide when the detected sound is a knock or not
// these variables will change:
int Hit;
int sensorReading0 = 0;
int sensorReading1 = 0; // variable to store the value read from the sensor pin
void setup(){
Serial.begin(2000000);
}
void loop(){
sensorReading0 = analogRead(knockSensor0);
sensorReading1 = analogRead(knockSensor1);
if (sensorReading0>Threshold1){
Serial.print(sensorReading0);
Serial.print(";");
Serial.println(sensorReading1);
}
}
With the serial output i get these results:
Blue lines the piezo near the hammer, red lines 25cm away.
/*Final Project Fabacademy 2018 - Getting the peaks measurements for
* Ice Thickness Measuring Device
* http://archive.fabacademy.org/2018/labs/fablabamsterdam/students/henk-buursen/index.html
*
*
*/
// These constants won't change:
const int currentPin = A0; // pin that the current sensor is attached to
const int echoPin = A1; // pin that the voltage sensor is attached to
const int threshold = 61; // the current draw threshold level that's in the range of the analog input
unsigned long starTime = 0; // global variable
unsigned long interval = 5000; // 5 seconds
bool relayFlag = false;
byte attempts = 0;
void setup() {
// initialize the RELAY pins as an output:
// initialize serial communications:
Serial.begin(9600);
}
void loop() {
// read the value of the current sensor:
int analogValue = analogRead(currentPin);
// if the analog value is high enough, power the relay:
if (relayFlag == false && attempts < 3 && analogValue > threshold)
{
starTime = millis(); // start timer
Serial.println("Start");
}
if(relayFlag == false && millis() - starTime >= 100)
{
// current time - start time >= 5 seconds
int analogValue1 = analogRead(echoPin);
if(echoPin > 1000)
relayFlag = true;
if (starTime == 0) {
}
else if (starTime>=100) {
Serial.print("Stop");
Serial.print(" ");
Serial.println(starTime);}
starTime = 0;
}
}
Calculating the right peaks
not yet implemented…
- I have to detect the peak values coming in from the two piezo.
- Then i've to calculate the time difference between the peaks.
- and then based on the time difference caclulations have to be done to get the thickness of the ice
high peak detection
not yet implemented in the final code!
This code i found on the arduino forum and looks like the thing to tryout:
#include <Compatibility_v2.5.h>
#include <MIDI.h>
int Threshold = 200;
int velocity;
int Hit;
int PadNote1 = 35;
int PadNote2 = 38;
int PadNote3 = 41;
int PadNote4 = 43;
int PadNote5 = 46;
int PadNote6 = 49;
void setup(){
for (int i = 2;i<=7;i++){
pinMode (i,OUTPUT);
}
pinMode (13,OUTPUT);
BlinkLed (3,500);
Serial.begin(38400);
}
void loop(){
for (int i = 0;i<=5;i++){ //Cycle through ADC channels.
if (analogRead(i)>Threshold){ //If current channel reading exceeds threshold
Hit = AnalogMaxima (i,Threshold,2); //find local maxima and return value.
if (Hit == 1025 || Hit == 0){ //if still ascending or below threshold,
break; //go to next ADC channel.
}
else{
"do something"
}
}
}
}
Oled: Show the measured thickness
Not yet implemented. At the moment the oled gives the values it gets from both piezos.