/
Pyr0_Piezo_Sensor_V2.x.x.cpp
183 lines (145 loc) · 5.75 KB
/
Pyr0_Piezo_Sensor_V2.x.x.cpp
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
Piezoelectric Z-Axis sensor using AtMega88/168/328 (AtMega 48 doesnt have enough memory for this version)
This sketch reads a piezo element to detect a touch of the printer's nozzle to the bed.
The sense pin is tied to an interrupt, which is pulled high by internal pullup resistor.
When the piezo touches the bed, the amplification circuit will draw the interrupt pin low
and the atmega will output a pulse based on the programmed trigger duration
* PD2 INT0 (Piezo In 'D2')
* D7 PCINT23 (Trigger OUT 'D7')
* PC0 ADC0 (Voltage Reference Check 'A0')
* PC1 ADC1 (Sensitivity Adjustment Check 'A1')
* PD4 PCINT20 (Error feedback LED 'D4')
* PB6 PCINT6 (Voltage Adjustment Resistor 0 'D20')
* PB7 PCINT7 (Voltage Adjustment Resistor 1 'D21')
* PD5 T1 (Voltage Adjustment Resistor 2 'D5')
* PD6 PCINT22 (Voltage Adjustment Resistor 3 'D6')
* PB1 OC1A (Comparator VRef PWM Out 'D9')
* PD3 OC2B (Voltage Follower VRef PWM Out 'D3')
Schematics for this project can be found here: https://github.com/pyr0ball/pyr0piezo/tree/master/docs/Schematics
For Arduino IDE use MCUdude MiniCore: https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
created 2/18/2019
by Alan "pyr0ball" Weinstock
This code is in the public domain.
------------------------------------------------------------*/
/*-----------------------------------------------------------
To set the below parameters using serial input, use the following:
To change trigger active duration: TRG_D [integer for milliseconds]
To change gain factor: GAIN_F [integer for gain state - see note*]
To change ADC hysteresis value: HYST [integer]
To change sensor input pullup vRef low threshold: VFOL [integer in millivolts]
To change comparator trigger high threshold: VCOMP [integer in millivolts]
To change the duration between ADC measurements: LOOP_D [integer in milliseconds]
To update the internal vRef constant value **(see notes below): CONST [long value]
You can also enable or disable DEBUG output with: DEBUG [0|1]
You can query the current configuration with: CONFIG
You can query the current state (including ADC measurements) with: STATE
To reset all settings to defaults, use: RESET
These commands should be wrapped in this format:
CMD INT
Examples:
GAIN_F 3 <~ set gain factor to index 3 (6x)
VFOL 2350 <~ set the vref floor to 2.35V
DEBUG 1 <~ Enable debug output
STATE <~ display current sensor status
*Note for Gain Factor:
The gain STATE is representative of these values:
0 = 3x
1 = 3.5x
2 = 4.33x
3 = 6x
4 = 11x
**Note for calibrating internal 1.1v vRef:
The ADC reading function assumes an "ideal" multiplier constant. Each Atmega
chip is slightly different, so it won't be completely accurate without tuning.
Most of the time this won't be necessary, so don't mess with this if you don't
know what you're doing!
The reading can be fine-tuned by using a multimeter, and this equation:
scale_constant = internal1.1Ref * 1023 * 1000
where
internal1.1Ref = 1.1 * Vcc1 (per voltmeter) / Vcc2 (per readVcc() function)
If the scale_constant calculated is different from the default 1125300,
update the voltMeterConstant variable in pP_config.h with the correct value
------------------------------------------------------------*/
/* Debug output verbose mode will continuously output sensor readings
rather than waiting for user input */
//#define VERBOSE true
// Headers, variables, and functions
#include <Arduino.h>
#include <EEPROM.h>
#include "LightChrono.h"
#include "pP_pins.h"
#include "pP_config.h"
#include "pP_volatile.h"
#include "pP_function.h"
#include "pP_serial.h"
// i2c input toggle. Uncomment to enable
//#define I2C_INPUT true
void setup() {
pinMode(TRG_OUT, OUTPUT); // declare the Trigger as as OUTPUT
pinMode(ERR_LED, OUTPUT);
pinMode(Z_TRG, INPUT_PULLUP); // declare z-sense input with pullup
pinMode(V_FOLLOW_PIN, INPUT);
pinMode(VCOMP_SENSE_PIN, INPUT);
pinMode(GADJ_R0, INPUT); // declare input to set high impedance
pinMode(GADJ_R1, INPUT); // declare input to set high impedance
pinMode(GADJ_R2, INPUT); // declare input to set high impedance
pinMode(GADJ_R3, INPUT); // declare input to set high impedance
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(Z_TRG), pulse, FALLING);
Serial.println("Initializing Pyr0-Piezo Sensor...");
restoreConfig();
adjustGain();
}
/*------------------------------------------------*/
void loop() {
if (mainLoop.hasPassed(LOOP_DUR)) {
mainLoop.restart();
// Blink LED's on init
if (BlinkCount > 0) {
BlinkState = !BlinkState;
digitalWrite(ERR_LED, BlinkState);
digitalWrite(TRG_OUT, BlinkState);
--BlinkCount;
}
// Get Serial Input
serialInput();
// Set any new parameters from serial input
if (serialIncoming) {
updateParams();
}
// Set the amplification gain factor
adjustGain();
// Check voltage of first and second stages and compare against thresholds
readVin();
VComp = analogRead(VCOMP_SENSE_PIN);
VFol = analogRead(V_FOLLOW_PIN);
VLast = VOld - Vin;
if (VLast > Hyst || VLast < -Hyst) {
// Voltage Follower adjustment
adjustFollow();
// Voltage Comparator adjustment
adjustComp();
// Alert the user that auto-calibration is ongoing
ERR_STATE = 1;
} else {
ERR_STATE = 0;
}
// Blink LED's on init
if (BlinkCount > 0) {
BlinkState = !BlinkState;
digitalWrite(ERR_LED, BlinkState);
digitalWrite(TRG_OUT, BlinkState);
--BlinkCount;
} else {
// Check for error state
checkError();
}
// Print state if debug is on
if (Debug > 0) {
serialPrintState();
}
// Sets trigger output state to false after completing loop
//digitalWrite(TRG_OUT, HIGH);
sensorHReading = 0;
}
}