more rp2040 stuff
This commit is contained in:
18
extensions/platformio/HX711_read/platformio.ini
Normal file
18
extensions/platformio/HX711_read/platformio.ini
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:waveshare_rp2040_zero]
|
||||||
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||||
|
board = waveshare_rp2040_zero
|
||||||
|
framework = arduino
|
||||||
|
monitor_speed = 115200
|
||||||
|
lib_deps =
|
||||||
|
https://github.com/Chris--A/Keypad
|
||||||
|
bogde/HX711@^0.7.5
|
||||||
84
extensions/platformio/HX711_read/src/main.cpp
Normal file
84
extensions/platformio/HX711_read/src/main.cpp
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "HX711.h"
|
||||||
|
|
||||||
|
const int LOADCELL_DOUT_PIN = 2;
|
||||||
|
const int LOADCELL_SCK_PIN = 3;
|
||||||
|
|
||||||
|
HX711 scale;
|
||||||
|
|
||||||
|
float smoothedWeight = 0.0;
|
||||||
|
float alpha = 0.3;
|
||||||
|
float calibration_factor = 111.17;
|
||||||
|
float known_weight = 796.0;
|
||||||
|
|
||||||
|
// Stability Lock Variables
|
||||||
|
float lastDisplayedWeight = 0.0;
|
||||||
|
const float STABILITY_THRESHOLD = 0.5;
|
||||||
|
|
||||||
|
void calibrateScale() {
|
||||||
|
Serial.println("--- Calibration Mode ---");
|
||||||
|
Serial.println("1. Clear scale, type 't' to tare.");
|
||||||
|
Serial.print("2. Place "); Serial.print(known_weight); Serial.println("g weight.");
|
||||||
|
Serial.println("3. Type 'c' to confirm weight.");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (Serial.available()) {
|
||||||
|
char c = Serial.read();
|
||||||
|
if (c == 't') {
|
||||||
|
scale.tare();
|
||||||
|
Serial.println("Tared! Place weight and type 'c'...");
|
||||||
|
} else if (c == 'c') {
|
||||||
|
long reading = scale.get_value(15);
|
||||||
|
calibration_factor = (float)reading / known_weight;
|
||||||
|
scale.set_scale(calibration_factor);
|
||||||
|
Serial.print("New Factor: "); Serial.println(calibration_factor);
|
||||||
|
Serial.println("Calibration Done! Exiting mode.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
|
||||||
|
scale.set_gain(128);
|
||||||
|
scale.set_scale(calibration_factor);
|
||||||
|
scale.tare();
|
||||||
|
Serial.println("HX711 Ready (Stable Lock Mode)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (scale.is_ready()) {
|
||||||
|
float currentReading = scale.get_units(1);
|
||||||
|
smoothedWeight = (alpha * currentReading) + (1.0 - alpha) * smoothedWeight;
|
||||||
|
|
||||||
|
// 1. Calculate the intended new display value
|
||||||
|
float targetWeight = round(smoothedWeight * 2.0) / 2.0;
|
||||||
|
if (abs(targetWeight) < 1.0) targetWeight = 0.0;
|
||||||
|
|
||||||
|
// 2. Stability Check
|
||||||
|
// Only update lastDisplayedWeight if the change exceeds the threshold
|
||||||
|
if (abs(targetWeight - lastDisplayedWeight) >= STABILITY_THRESHOLD) {
|
||||||
|
lastDisplayedWeight = targetWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("Weight: ");
|
||||||
|
Serial.print(lastDisplayedWeight, 1);
|
||||||
|
Serial.println(" g");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Serial.available()) {
|
||||||
|
char cmd = Serial.read();
|
||||||
|
if (cmd == 't') {
|
||||||
|
scale.tare();
|
||||||
|
smoothedWeight = 0;
|
||||||
|
lastDisplayedWeight = 0; // Force display to zero immediately
|
||||||
|
Serial.println(">> Tared");
|
||||||
|
} else if (cmd == 'k') {
|
||||||
|
calibrateScale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
const int SCLK_PIN = 1;
|
|
||||||
const int DOUT_PIN = 2;
|
|
||||||
|
|
||||||
long tareOffset = 0;
|
|
||||||
float calibrationFactor = 74.17; //1.0 by default, callibrated by placing 796 weight and callibrating
|
|
||||||
float smoothedWeight = 0.0;
|
|
||||||
float alpha = 0.15; // Adjustment: 0.05 (very smooth/slow) to 0.3 (jumpy/fast)
|
|
||||||
|
|
||||||
long readSD10809() {
|
|
||||||
long data = 0;
|
|
||||||
|
|
||||||
// Wait for DRDY to go LOW
|
|
||||||
uint32_t timeout = millis();
|
|
||||||
while (digitalRead(DOUT_PIN) == HIGH) {
|
|
||||||
if (millis() - timeout > 100) return -1; // 20Hz rate is 50ms
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read 24-bit ADC result [cite: 158, 160]
|
|
||||||
for (int i = 0; i < 24; i++) {
|
|
||||||
digitalWrite(SCLK_PIN, HIGH);
|
|
||||||
delayMicroseconds(1);
|
|
||||||
data = (data << 1) | digitalRead(DOUT_PIN);
|
|
||||||
digitalWrite(SCLK_PIN, LOW);
|
|
||||||
delayMicroseconds(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send 3 extra pulses (Total 27) to keep Channel A at 128x Gain [cite: 152, 161]
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
digitalWrite(SCLK_PIN, HIGH);
|
|
||||||
delayMicroseconds(1);
|
|
||||||
digitalWrite(SCLK_PIN, LOW);
|
|
||||||
delayMicroseconds(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle 24-bit Two's Complement sign extension [cite: 108]
|
|
||||||
if (data & 0x800000) data |= 0xFF000000;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getAverageReading(int samples) {
|
|
||||||
long sum = 0;
|
|
||||||
int count = 0;
|
|
||||||
while (count < samples) {
|
|
||||||
long val = readSD10809();
|
|
||||||
if (val != -1) {
|
|
||||||
sum += val;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum / samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tare() {
|
|
||||||
Serial.println("Taring... keep scale still.");
|
|
||||||
tareOffset = getAverageReading(20);
|
|
||||||
Serial.print("New Offset: ");
|
|
||||||
Serial.println(tareOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void calibrate(float knownWeightGrams) {
|
|
||||||
long currentRaw = getAverageReading(20);
|
|
||||||
calibrationFactor = (float)(currentRaw - tareOffset) / knownWeightGrams;
|
|
||||||
Serial.print("Calibration Factor set to: ");
|
|
||||||
Serial.println(calibrationFactor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
pinMode(SCLK_PIN, OUTPUT);
|
|
||||||
pinMode(DOUT_PIN, INPUT);
|
|
||||||
|
|
||||||
// Give the chip time to stabilize (2 cycles for SD10809) [cite: 142]
|
|
||||||
delay(500);
|
|
||||||
tare();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
long raw = readSD10809();
|
|
||||||
|
|
||||||
if (raw != -1) {
|
|
||||||
// 1. Calculate current instantaneous weight
|
|
||||||
float currentWeight = (raw - tareOffset) / calibrationFactor;
|
|
||||||
|
|
||||||
// 2. Apply EMA Filter
|
|
||||||
smoothedWeight = (alpha * currentWeight) + (1.0 - alpha) * smoothedWeight;
|
|
||||||
|
|
||||||
// 3. Optional: "Auto-Zero" or Snap-to-Zero
|
|
||||||
// If the weight is within 0.05g of zero, just show 0.00
|
|
||||||
float displayWeight = smoothedWeight;
|
|
||||||
if (abs(displayWeight) < 0.05) {
|
|
||||||
displayWeight = 0.00;
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.print("Weight: ");
|
|
||||||
Serial.print(displayWeight, 2);
|
|
||||||
Serial.println(" g");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Example trigger for calibration via Serial
|
|
||||||
if (Serial.available()) {
|
|
||||||
char c = Serial.read();
|
|
||||||
if (c == 't') {
|
|
||||||
tare();
|
|
||||||
}
|
|
||||||
if (c == 'c') {
|
|
||||||
calibrate(796);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5
extensions/platformio/UART_SCALE_ALL/.gitignore
vendored
Normal file
5
extensions/platformio/UART_SCALE_ALL/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
||||||
10
extensions/platformio/UART_SCALE_ALL/.vscode/extensions.json
vendored
Normal file
10
extensions/platformio/UART_SCALE_ALL/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
|
]
|
||||||
|
}
|
||||||
37
extensions/platformio/UART_SCALE_ALL/include/README
Normal file
37
extensions/platformio/UART_SCALE_ALL/include/README
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the convention is to give header files names that end with `.h'.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||||
46
extensions/platformio/UART_SCALE_ALL/lib/README
Normal file
46
extensions/platformio/UART_SCALE_ALL/lib/README
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
This directory is intended for project specific (private) libraries.
|
||||||
|
PlatformIO will compile them to static libraries and link into the executable file.
|
||||||
|
|
||||||
|
The source code of each library should be placed in a separate directory
|
||||||
|
("lib/your_library_name/[Code]").
|
||||||
|
|
||||||
|
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||||
|
|
||||||
|
|--lib
|
||||||
|
| |
|
||||||
|
| |--Bar
|
||||||
|
| | |--docs
|
||||||
|
| | |--examples
|
||||||
|
| | |--src
|
||||||
|
| | |- Bar.c
|
||||||
|
| | |- Bar.h
|
||||||
|
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||||
|
| |
|
||||||
|
| |--Foo
|
||||||
|
| | |- Foo.c
|
||||||
|
| | |- Foo.h
|
||||||
|
| |
|
||||||
|
| |- README --> THIS FILE
|
||||||
|
|
|
||||||
|
|- platformio.ini
|
||||||
|
|--src
|
||||||
|
|- main.c
|
||||||
|
|
||||||
|
Example contents of `src/main.c` using Foo and Bar:
|
||||||
|
```
|
||||||
|
#include <Foo.h>
|
||||||
|
#include <Bar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||||
|
libraries by scanning project source files.
|
||||||
|
|
||||||
|
More information about PlatformIO Library Dependency Finder
|
||||||
|
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||||
@@ -13,3 +13,4 @@ platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
|||||||
board = waveshare_rp2040_zero
|
board = waveshare_rp2040_zero
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
lib_deps = https://github.com/Chris--A/Keypad
|
||||||
50
extensions/platformio/UART_SCALE_ALL/src/TM1621_Config.h
Normal file
50
extensions/platformio/UART_SCALE_ALL/src/TM1621_Config.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#ifndef TM1621_CONFIG_H
|
||||||
|
#define TM1621_CONFIG_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
const uint8_t digitMap[] = {
|
||||||
|
0b11111100, // 0
|
||||||
|
0b00000110, // 1
|
||||||
|
0b01011011, // 2
|
||||||
|
0b01001111, // 3
|
||||||
|
0b01100110, // 4
|
||||||
|
0b01101101, // 5
|
||||||
|
0b01111101, // 6
|
||||||
|
0b00000111, // 7
|
||||||
|
0b01111111, // 8
|
||||||
|
0b01101111 // 9
|
||||||
|
};
|
||||||
|
|
||||||
|
const int arrows[] = {283,363,183,203}; //tare,?,?,Zero
|
||||||
|
const int battery[] = {63,83,103}; //LOW / MED / FULL
|
||||||
|
|
||||||
|
// Following your pattern: {A, B, C, D, E, F, G}
|
||||||
|
const int row1_d1[] = {300, 301, 302, 313, 312, 310, 311}; // Addresses 30 & 31
|
||||||
|
const int row1_d2[] = {280, 281, 282, 293, 292, 290, 291}; // Addresses 28 & 29
|
||||||
|
const int row1_d3[] = {260, 261, 262, 273, 272, 270, 271}; // Addresses 26 & 27
|
||||||
|
const int row1_d4[] = {240, 241, 242, 253, 252, 250, 251}; // Addresses 24 & 25
|
||||||
|
const int row1_d5[] = {220, 221, 222, 233, 232, 230, 231}; // Addresses 22 & 23
|
||||||
|
const int row1_decimal[] = {263,232,223}; //XX.X.X.X
|
||||||
|
|
||||||
|
const int row2_d1[] = {200, 201, 202, 213, 212, 210, 211}; // Addresses 20 & 21
|
||||||
|
const int row2_d2[] = {180, 181, 182, 193, 192, 190, 191}; // Addresses 18 & 19
|
||||||
|
const int row2_d3[] = {160, 161, 162, 173, 172, 170, 171}; // Addresses 16 & 17
|
||||||
|
const int row2_d4[] = {140, 141, 142, 153, 152, 150, 151}; // Addresses 14 & 15
|
||||||
|
const int row2_d5[] = {120, 121, 122, 133, 132, 130, 131}; // Addresses 12 & 13
|
||||||
|
const int row2_decimal[] = {163,143,123}; //XX.X.X.X
|
||||||
|
|
||||||
|
const int row3_d1[] = {100, 101, 102, 113, 112, 110, 111}; // Addresses 10 & 11
|
||||||
|
const int row3_d2[] = {80, 81, 82, 93, 92, 90, 91}; // Addresses 8 & 9
|
||||||
|
const int row3_d3[] = {60, 61, 62, 73, 72, 70, 71}; // Addresses 6 & 7
|
||||||
|
const int row3_d4[] = {40, 41, 42, 53, 52, 50, 51}; // Addresses 4 & 5
|
||||||
|
const int row3_d5[] = {20, 21, 22, 33, 32, 30, 31}; // Addresses 2 & 3
|
||||||
|
const int row3_d6[] = {0, 1, 2, 13, 12, 10, 11}; // Addresses 0 & 1
|
||||||
|
const int row3_decimal[] = {43,23,3}; //XX.X.X.X
|
||||||
|
|
||||||
|
const int* digitsRow1[] = {row1_d1, row1_d2, row1_d3, row1_d4, row1_d5};
|
||||||
|
const int* digitsRow2[] = {row2_d1, row2_d2, row2_d3, row2_d4, row2_d5};
|
||||||
|
const int* digitsRow3[] = {row3_d1, row3_d2, row3_d3, row3_d4, row3_d5, row3_d6};
|
||||||
|
|
||||||
|
const int* decimals[] = {row1_decimal, row2_decimal, row3_decimal};
|
||||||
|
#endif
|
||||||
270
extensions/platformio/UART_SCALE_ALL/src/main.cpp
Normal file
270
extensions/platformio/UART_SCALE_ALL/src/main.cpp
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "TM1621_Config.h"
|
||||||
|
#include <Keypad.h>
|
||||||
|
|
||||||
|
#define SCLK_SDI0819 1
|
||||||
|
#define DOUT_SDI0819 2
|
||||||
|
#define LCD_DATA 3
|
||||||
|
#define LCD_WR 4
|
||||||
|
#define LCD_CS 5
|
||||||
|
#define BUZZER_PIN 6
|
||||||
|
#define BACKLIGHT_PIN 7
|
||||||
|
|
||||||
|
int currentAddr = 0;
|
||||||
|
int currentBit = 0;
|
||||||
|
|
||||||
|
void writeBits(uint32_t data, uint8_t count) {
|
||||||
|
for (int8_t i = count - 1; i >= 0; i--) {
|
||||||
|
digitalWrite(LCD_WR, LOW);
|
||||||
|
digitalWrite(LCD_DATA, (data >> i) & 0x01);
|
||||||
|
digitalWrite(LCD_WR, HIGH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendCmd(uint8_t cmd) {
|
||||||
|
digitalWrite(LCD_CS, LOW);
|
||||||
|
writeBits(0x04, 3); // Binary 100 [cite: 432]
|
||||||
|
writeBits(cmd, 8); // Command [cite: 413, 534]
|
||||||
|
writeBits(0, 1); // X bit [cite: 416]
|
||||||
|
digitalWrite(LCD_CS, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeAddr(uint8_t addr, uint8_t data) {
|
||||||
|
digitalWrite(LCD_CS, LOW);
|
||||||
|
uint16_t header = (0x05 << 6) | (addr & 0x3F); // Mode 101 [cite: 475]
|
||||||
|
writeBits(header, 9);
|
||||||
|
writeBits(data & 0x0F, 4); // 4 bits of data [cite: 475]
|
||||||
|
digitalWrite(LCD_CS, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDisplay() {
|
||||||
|
// Clear all segments first
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
writeAddr(i, 0x00);
|
||||||
|
}
|
||||||
|
// Light up only the current bit
|
||||||
|
writeAddr(currentAddr, (1 << currentBit));
|
||||||
|
|
||||||
|
Serial.print(">>> CURRENT - Address: ");
|
||||||
|
Serial.print(currentAddr);
|
||||||
|
Serial.print(" | Bit (COM): ");
|
||||||
|
Serial.println(currentBit);
|
||||||
|
Serial.println("Enter 'n' for Next, 'p' for Prev:");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t shadowRAM[32] = {0};
|
||||||
|
|
||||||
|
void writeMappedSegment(int aab, bool state) {
|
||||||
|
int addr = aab / 10;
|
||||||
|
int bit = aab % 10;
|
||||||
|
|
||||||
|
if (state) shadowRAM[addr] |= (1 << bit);
|
||||||
|
else shadowRAM[addr] &= ~(1 << bit);
|
||||||
|
|
||||||
|
writeAddr(addr, shadowRAM[addr]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayDigit(const int segments[], int number) {
|
||||||
|
uint8_t bits = digitMap[number % 10];
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
// We check Bit 0, then Bit 1, etc.
|
||||||
|
// This maps i=0 to Segment A, i=1 to Segment B...
|
||||||
|
bool state = (bits >> i) & 0x01;
|
||||||
|
writeMappedSegment(segments[i], state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printToRow(int row, long value, int decimalPos = 0) {
|
||||||
|
const int** currentRow;
|
||||||
|
int numDigits;
|
||||||
|
|
||||||
|
// Select row configuration
|
||||||
|
switch(row) {
|
||||||
|
case 1: currentRow = digitsRow1; numDigits = 5; break;
|
||||||
|
case 2: currentRow = digitsRow2; numDigits = 5; break;
|
||||||
|
case 3: currentRow = digitsRow3; numDigits = 6; break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the number right-aligned
|
||||||
|
long tempValue = value;
|
||||||
|
for (int i = numDigits - 1; i >= 0; i--) {
|
||||||
|
if (tempValue > 0 || i == numDigits - 1) { // Show at least one digit
|
||||||
|
displayDigit(currentRow[i], tempValue % 10);
|
||||||
|
tempValue /= 10;
|
||||||
|
} else {
|
||||||
|
// Clear leading zeros (all segments off)
|
||||||
|
for (int s = 0; s < 7; s++) writeMappedSegment(currentRow[i][s], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Decimal Points (if applicable for that row)
|
||||||
|
if (decimalPos > 0 && decimalPos <= 3) {
|
||||||
|
writeMappedSegment(decimals[row-1][decimalPos-1], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupDisplay() {
|
||||||
|
pinMode(LCD_DATA, OUTPUT);
|
||||||
|
pinMode(LCD_WR, OUTPUT);
|
||||||
|
pinMode(LCD_CS, OUTPUT);
|
||||||
|
digitalWrite(LCD_CS, HIGH); // Initialize serial interface [cite: 443]
|
||||||
|
|
||||||
|
sendCmd(0x01); // SYS EN [cite: 534]
|
||||||
|
sendCmd(0x29); // BIAS 1/3, 4 COM [cite: 420, 544]
|
||||||
|
sendCmd(0x03); // LCD ON [cite: 534]
|
||||||
|
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
const byte ROWS = 4;
|
||||||
|
const byte COLS = 5;
|
||||||
|
|
||||||
|
char keys[ROWS][COLS] = {{'1', '2', '3', 'C', 'T'},
|
||||||
|
{'4', '5', '6', 'A', 'Z'},
|
||||||
|
{'7', '8', '9', 'X', 'Y'},
|
||||||
|
{'0', '.', 'S', 'M', 'L'}};
|
||||||
|
|
||||||
|
byte rowPins[ROWS] = {8,9, 10, 11};
|
||||||
|
byte colPins[COLS] = {12,13,14,15,16};
|
||||||
|
|
||||||
|
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
|
||||||
|
|
||||||
|
void playBeep() {
|
||||||
|
analogWrite(BUZZER_PIN, 10);
|
||||||
|
delay(50);
|
||||||
|
analogWrite(BUZZER_PIN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long tareOffset = 0;
|
||||||
|
float calibrationFactor =
|
||||||
|
74.17; // 1.0 by default, callibrated by placing 796 weight and callibrating
|
||||||
|
|
||||||
|
long readSD10809() {
|
||||||
|
long data = 0;
|
||||||
|
|
||||||
|
// Wait for DRDY to go LOW
|
||||||
|
uint32_t timeout = millis();
|
||||||
|
while (digitalRead(DOUT_SDI0819) == HIGH) {
|
||||||
|
if (millis() - timeout > 100)
|
||||||
|
return -1; // 20Hz rate is 50ms
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read 24-bit ADC result [cite: 158, 160]
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
digitalWrite(SCLK_SDI0819, HIGH);
|
||||||
|
delayMicroseconds(1);
|
||||||
|
data = (data << 1) | digitalRead(DOUT_SDI0819);
|
||||||
|
digitalWrite(SCLK_SDI0819, LOW);
|
||||||
|
delayMicroseconds(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send 3 extra pulses (Total 27) to keep Channel A at 128x Gain [cite: 152,
|
||||||
|
// 161]
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
digitalWrite(SCLK_SDI0819, HIGH);
|
||||||
|
delayMicroseconds(1);
|
||||||
|
digitalWrite(SCLK_SDI0819, LOW);
|
||||||
|
delayMicroseconds(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle 24-bit Two's Complement sign extension [cite: 108]
|
||||||
|
if (data & 0x800000)
|
||||||
|
data |= 0xFF000000;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
long getAverageReading(int samples) {
|
||||||
|
long sum = 0;
|
||||||
|
int count = 0;
|
||||||
|
while (count < samples) {
|
||||||
|
long val = readSD10809();
|
||||||
|
if (val != -1) {
|
||||||
|
sum += val;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum / samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tare() {
|
||||||
|
Serial.println("Taring... keep scale still.");
|
||||||
|
tareOffset = getAverageReading(20);
|
||||||
|
Serial.print("New Offset: ");
|
||||||
|
Serial.println(tareOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void calibrate(float knownWeightGrams) {
|
||||||
|
long currentRaw = getAverageReading(20);
|
||||||
|
calibrationFactor = (float)(currentRaw - tareOffset) / knownWeightGrams;
|
||||||
|
Serial.print("Calibration Factor set to: ");
|
||||||
|
Serial.println(calibrationFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupADC() {
|
||||||
|
pinMode(SCLK_SDI0819, OUTPUT);
|
||||||
|
pinMode(DOUT_SDI0819, INPUT);
|
||||||
|
|
||||||
|
// Give the chip time to stabilize (2 cycles for SD10809) [cite: 142]
|
||||||
|
delay(500);
|
||||||
|
tare();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
setupDisplay();
|
||||||
|
setupADC();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
long raw = readSD10809();
|
||||||
|
|
||||||
|
if (kpd.getKeys()) {
|
||||||
|
for (int i = 0; i < LIST_MAX; i++) {
|
||||||
|
if (kpd.key[i].stateChanged) {
|
||||||
|
String msg = "";
|
||||||
|
switch (kpd.key[i].kstate) {
|
||||||
|
case PRESSED:
|
||||||
|
msg = " PRESSED.";
|
||||||
|
playBeep();
|
||||||
|
break;
|
||||||
|
case HOLD:
|
||||||
|
msg = " HOLD.";
|
||||||
|
break;
|
||||||
|
case RELEASED:
|
||||||
|
msg = " RELEASED.";
|
||||||
|
break;
|
||||||
|
case IDLE:
|
||||||
|
msg = " IDLE.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg != "") {
|
||||||
|
Serial.print("Key ");
|
||||||
|
Serial.print(kpd.key[i].kchar);
|
||||||
|
Serial.println(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw != -1) {
|
||||||
|
float displayWeight = (raw - tareOffset) / calibrationFactor;
|
||||||
|
|
||||||
|
Serial.print("Weight: ");
|
||||||
|
Serial.print(displayWeight, 2);
|
||||||
|
Serial.println(" g");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example trigger for calibration via Serial
|
||||||
|
if (Serial.available()) {
|
||||||
|
char c = Serial.read();
|
||||||
|
if (c == 't') {
|
||||||
|
tare();
|
||||||
|
}
|
||||||
|
if (c == 'c') {
|
||||||
|
calibrate(796);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
extensions/platformio/UART_SCALE_ALL/test/README
Normal file
11
extensions/platformio/UART_SCALE_ALL/test/README
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
This directory is intended for PlatformIO Test Runner and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PlatformIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||||
Binary file not shown.
@@ -54,11 +54,6 @@ void setup() {
|
|||||||
pinMode(LCD_CS, OUTPUT);
|
pinMode(LCD_CS, OUTPUT);
|
||||||
digitalWrite(LCD_CS, HIGH); // Initialize serial interface [cite: 443]
|
digitalWrite(LCD_CS, HIGH); // Initialize serial interface [cite: 443]
|
||||||
|
|
||||||
Serial.begin(9600);
|
|
||||||
// while (!Serial);
|
|
||||||
|
|
||||||
Serial.println("--- TM1621 Interactive Mapper ---");
|
|
||||||
|
|
||||||
sendCmd(0x01); // SYS EN [cite: 534]
|
sendCmd(0x01); // SYS EN [cite: 534]
|
||||||
sendCmd(0x29); // BIAS 1/3, 4 COM [cite: 420, 544]
|
sendCmd(0x29); // BIAS 1/3, 4 COM [cite: 420, 544]
|
||||||
sendCmd(0x03); // LCD ON [cite: 534]
|
sendCmd(0x03); // LCD ON [cite: 534]
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
|||||||
board = waveshare_rp2040_zero
|
board = waveshare_rp2040_zero
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
lib_deps = https://github.com/Chris--A/Keypad
|
||||||
|
|||||||
@@ -1,76 +1,70 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <Keypad.h>
|
||||||
|
|
||||||
const int BUZZER_PIN = 6;
|
#define BUZZER_PIN 9
|
||||||
const int pins[] = {0, 1, 2, 3, 4, 5, 7};
|
|
||||||
const int numPins = 7;
|
|
||||||
|
|
||||||
struct KeyMap {
|
const byte ROWS = 4;
|
||||||
int strobe;
|
const byte COLS = 5;
|
||||||
int target;
|
|
||||||
char key;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Your discovered mapping
|
char keys[ROWS][COLS] = {{'1', '2','3','C','T'},
|
||||||
KeyMap keypad[] = {{7, 1, '1'}, {7, 2, '2'}, {3, 7, '3'}, {5, 0, 'C'},
|
{'4', '5','6','A','Z'},
|
||||||
{7, 0, 'T'}, {4, 1, 'm'}, {1, 2, 'Y'}, {5, 3, '6'},
|
{'7', '8','9','X','Y'},
|
||||||
{1, 0, '+'}, {2, 0, 'Z'}, {1, 5, '7'}, {5, 2, 'U'},
|
{'0', '.','S','M','L'}};
|
||||||
{2, 5, '8'}, {3, 5, '9'}, {2, 4, 'M'}, {3, 1, '4'},
|
|
||||||
{0, 2, '5'}, {3, 4, 'P'}, {4, 0, '$'}, {0, 4, 'L'}};
|
|
||||||
|
|
||||||
void setup() {
|
byte rowPins[ROWS] = {0,1,2,3};
|
||||||
Serial.begin(115200);
|
byte colPins[COLS] = {4,5,6,7,8};
|
||||||
for (int p : pins) {
|
|
||||||
pinMode(p, INPUT_PULLUP);
|
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
|
||||||
}
|
|
||||||
// Keep buzzer pin high-impedance so it doesn't sink the matrix
|
unsigned long loopCount = 0;
|
||||||
pinMode(BUZZER_PIN, INPUT_PULLUP);
|
unsigned long startTime;
|
||||||
}
|
|
||||||
|
|
||||||
void playBeep() {
|
void playBeep() {
|
||||||
analogWrite(BUZZER_PIN, 10);
|
analogWrite(BUZZER_PIN, 10);
|
||||||
|
delay(50);
|
||||||
delay(50); // Beep duration
|
analogWrite(BUZZER_PIN, 0);
|
||||||
|
|
||||||
analogWrite(BUZZER_PIN, 0); // Turn it off
|
|
||||||
pinMode(BUZZER_PIN, INPUT_PULLUP); // Reset to input for the matrix
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char getKeyPressed() {
|
void setup() {
|
||||||
for (int s = 0; s < numPins; s++) {
|
Serial.begin(115200);
|
||||||
int strobe = pins[s];
|
startTime = millis();
|
||||||
|
|
||||||
pinMode(strobe, OUTPUT);
|
|
||||||
digitalWrite(strobe, LOW);
|
|
||||||
delayMicroseconds(50);
|
|
||||||
|
|
||||||
for (int i = 0; i < numPins; i++) {
|
|
||||||
int target = pins[i];
|
|
||||||
if (target == strobe)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (digitalRead(target) == LOW) {
|
|
||||||
for (int k = 0; k < 20; k++) {
|
|
||||||
if (keypad[k].strobe == strobe && keypad[k].target == target) {
|
|
||||||
|
|
||||||
// Visual and Audio feedback
|
|
||||||
Serial.print("Pressed: ");
|
|
||||||
Serial.println(keypad[k].key);
|
|
||||||
playBeep();
|
|
||||||
|
|
||||||
while (digitalRead(target) == LOW)
|
|
||||||
; // Wait for release
|
|
||||||
pinMode(strobe, INPUT_PULLUP);
|
|
||||||
return keypad[k].key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pinMode(strobe, INPUT_PULLUP);
|
|
||||||
}
|
|
||||||
return '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
getKeyPressed();
|
loopCount++;
|
||||||
delay(10);
|
if ((millis() - startTime) > 5000) {
|
||||||
|
Serial.print("Average loops per second = ");
|
||||||
|
Serial.println(loopCount / 5);
|
||||||
|
startTime = millis();
|
||||||
|
loopCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kpd.getKeys()) {
|
||||||
|
for (int i = 0; i < LIST_MAX; i++) {
|
||||||
|
if (kpd.key[i].stateChanged) {
|
||||||
|
String msg = "";
|
||||||
|
switch (kpd.key[i].kstate) {
|
||||||
|
case PRESSED:
|
||||||
|
msg = " PRESSED.";
|
||||||
|
playBeep();
|
||||||
|
break;
|
||||||
|
case HOLD:
|
||||||
|
msg = " HOLD.";
|
||||||
|
break;
|
||||||
|
case RELEASED:
|
||||||
|
msg = " RELEASED.";
|
||||||
|
break;
|
||||||
|
case IDLE:
|
||||||
|
msg = " IDLE.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg != "") {
|
||||||
|
Serial.print("Key ");
|
||||||
|
Serial.print(kpd.key[i].kchar);
|
||||||
|
Serial.println(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user