Last active
July 27, 2020 16:10
-
-
Save Andrei-Pozolotin/e7bf413e2438863a04c2497258662bec to your computer and use it in GitHub Desktop.
Z-probe-on-smd-resistors-2512 / better code / https://github.com/IvDm/Z-probe-on-smd-resistors-2512/issues/7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// https://github.com/bogde/HX711 | |
// | |
// sensor setup: | |
// * 5V supply (from nano) | |
// * 128 gain (library config) | |
// * +-20 mV input range (derived from gain) | |
// * int32_t output range (library convention) | |
// * 80 Hz (12.5 ms) sample rate (jumper on board) | |
// | |
#include <Arduino.h> | |
#include "avg.h" | |
#include "log.h" | |
#include "time.h" | |
#include <HX711.h> | |
// host communication | |
const long SERIAL_RATE = 1000000; | |
// sensor/nano connection | |
const int SENSOR_PIN_DATA = 2; // sensor to nano | |
const int SENSOR_PIN_SCLK = 3; // nano to sensor | |
// sensor-dependent experimental value constant | |
// threshold sensor change values for on/off event detection | |
const int32_t MICRO_VOLT = 100000; // based on hx711 supply/gain | |
const int32_t DELTA_ACTIVE = 2 * MICRO_VOLT; | |
const int32_t DELTA_PASSIVE = 1 * MICRO_VOLT; | |
// sensor instance | |
HX711 sensor; | |
// signal smoothing | |
// 1 tick is HX711 ADC conversion period of 12.5 ms | |
MovingAverage moving_fast(2); // 2^2=4 ticks, 50 ms signal detection window | |
MovingAverage moving_slow(14); // 2^14=16384 ticks, 200 sec drifting context window | |
// trigger state | |
bool has_trigger = false; // is touch event detected | |
int32_t trigger_slow = 0; // trigger level for recovery | |
// track event duration | |
uint32_t time_active = 0; // touch event start time, millis | |
uint32_t time_passive = 0; // touch event finish time, millis | |
// nano output signal | |
void process_output(int level) { | |
digitalWrite(LED_BUILTIN, level); | |
} | |
// detect touch events | |
void process_trigger() { | |
const int32_t fast = moving_fast.average(); | |
const int32_t slow = moving_slow.average(); | |
const int32_t delta = fast - slow; | |
if (delta > 0) { // react only on proper direction | |
if (has_trigger) { | |
if (delta < DELTA_PASSIVE) { // detect turn off | |
has_trigger = false; // remember state | |
moving_slow.setup(trigger_slow); // recover to event start | |
process_output (LOW); // issue turn off | |
time_passive = millis(); // report event finish | |
} | |
} else { | |
if (delta > DELTA_ACTIVE) { // detect turn on | |
has_trigger = true; // remember state | |
trigger_slow = slow; // remember till event finish | |
process_output (HIGH); // issue turn on | |
time_active = millis(); // report event start | |
} | |
} | |
} | |
} | |
// report for debug, only after touch detection | |
void loopReport() { | |
if (time_active != 0 && time_passive != 0) { | |
const uint32_t time_delta = time_passive - time_active; | |
time_active = 0; | |
time_passive = 0; | |
const int32_t fast = moving_fast.average(); | |
const int32_t slow = moving_slow.average(); | |
Serial.print(" fast="); | |
Serial.print(fast); | |
Serial.print(" slow="); | |
Serial.print(slow); | |
Serial.print(" time="); | |
Serial.print(time_delta); | |
Serial.println(); | |
} | |
} | |
// | |
void setupSensor() { | |
sensor.begin(SENSOR_PIN_DATA, SENSOR_PIN_SCLK, 128); | |
} | |
// | |
void setupAverage() { | |
const int32_t value = sensor.read(); | |
trigger_slow = value; | |
moving_fast.setup(value); | |
moving_slow.setup(value); | |
} | |
void loopSensor() { | |
const int32_t value = sensor.read(); | |
moving_fast.update(value); | |
moving_slow.update(value); | |
process_trigger(); | |
} | |
// | |
void setupSerial(String stamp) { | |
Serial.begin(SERIAL_RATE); | |
log_println(); | |
log_println("version=" + stamp); | |
delay(1000); | |
} | |
// | |
void setupOutput() { | |
digitalWrite(LED_BUILTIN, LOW); | |
pinMode(LED_BUILTIN, OUTPUT); | |
} | |
// the setup function runs once | |
void setup() { | |
String stamp; | |
time_stamp(stamp); | |
setupSerial(stamp); | |
setupSensor(); | |
setupAverage(); | |
setupOutput(); | |
} | |
// the loop function runs forever | |
void loop() { | |
loopSensor(); | |
loopReport(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// average caculator | |
#include <Arduino.h> | |
#include "avg.h" | |
MovingAverage::MovingAverage(int16_t rate) { | |
decay_rate = rate; | |
} | |
void MovingAverage::setup(int32_t value) { | |
average_value = value; | |
average_total = (int64_t) value << decay_rate; | |
} | |
void MovingAverage::update(int32_t value) { | |
average_total += value; | |
average_total -= average_value; | |
average_value = average_total >> decay_rate; | |
} | |
int32_t MovingAverage::average() { | |
return average_value; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// average caclulator | |
#pragma once | |
class MovingAverage { | |
public: | |
// create with decay rate | |
MovingAverage(int16_t rate); | |
// provide initial average | |
void setup(int32_t value); | |
// apply sensor measurement | |
void update(int32_t value); | |
// report moving average | |
int32_t average(); | |
protected: | |
// exponential attenuation | |
int16_t decay_rate = 0; | |
// current moving average | |
int32_t average_value = 0; | |
// moving average integral | |
int64_t average_total = 0; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// logger settings | |
#pragma once | |
void log_print(char text[]) { | |
Serial.print(text); | |
} | |
void log_print(const __FlashStringHelper* text) { | |
Serial.print(text); | |
} | |
void log_println(char text[]) { | |
Serial.println(text); | |
} | |
void log_println(String text) { | |
Serial.println(text); | |
} | |
void log_println(const __FlashStringHelper* text) { | |
Serial.println(text); | |
} | |
void log_println() { | |
Serial.println(); | |
} | |
void log_print_bar() { | |
Serial.print(F("| ")); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// time support | |
#pragma once | |
#include <stdio.h> | |
#include <Time.h> | |
// https://stackoverflow.com/questions/1765014/convert-string-from-date-into-a-time-t | |
time_t time_parse(char const *date, char const *time) { | |
int year; | |
char month[5]; | |
tmElements_t tm; | |
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; // TODO PSTR | |
sscanf_P(date, PSTR("%s %hhd %d"), month, &tm.Day, &year); | |
sscanf_P(time, PSTR("%2hhd %*c %2hhd %*c %2hhd"), &tm.Hour, &tm.Minute, | |
&tm.Second); | |
tm.Year = year - 2000; | |
tm.Month = (strstr(month_names, month) - month_names) / 3 + 1; // TODO PSTR | |
return makeTime(tm); | |
} | |
// https://stackoverflow.com/questions/3053999/c-convert-time-t-to-string-with-format-yyyy-mm-dd-hhmmss | |
void time_stamp(String &value) { | |
tmElements_t tm; | |
time_t time = time_parse(__DATE__, __TIME__); | |
breakTime(time, tm); | |
char text[32]; | |
sprintf_P(text, PSTR("%02u%02u%02u-%02u%02u%02u"), tm.Year, tm.Month, | |
tm.Day, tm.Hour, tm.Minute, tm.Second); | |
value += text; | |
} |
this firmware better
yes, "better", only runs on nano, not attiny85
https://en.wikipedia.org/wiki/Arduino_Nano
why "better" is described here:
IvDm/Z-probe-on-smd-resistors-2512#7
IO connectors the same
no, connection is for nano
// sensor/nano connection
const int SENSOR_PIN_DATA = 2; // sensor to nano
const int SENSOR_PIN_SCLK = 3; // nano to sensor
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
Is this firmware better than the original? And are the IO connectors the same as the original PCB shared? Looking forward to your support.
Thank you.