Skip to content

Commit 8d4737c

Browse files
Add NeoPixel support. (#208)
* ADC_ATTEN_DB_12 is only defined in some versions? #198 * Hardware version detection. Fix v2.0 always-open squelch. #203 * Hardware version detection. Fix v2.0 always-open squelch. #203 * Cleaning formating/indenting from merge wackiness. No symantic changes. #203 * Added NeoPixel support. #207 * Removed dependency on Adafruit NeoPixel. Added breathing. #207 #208 * Cleanup proposal * Pedantic integer math changes. Explicit uint16_t cast, fix "color-1". #208 * #208 (review) #208 --------- Co-authored-by: Dmitry Kaukov <dkaukov@opentable.com>
1 parent 2e9f8af commit 8d4737c

File tree

3 files changed

+107
-44
lines changed

3 files changed

+107
-44
lines changed

microcontroller-src/README.md

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
## Table of Contents
22

3+
- [Table of Contents](#table-of-contents)
34
- [Prerequisites](#prerequisites)
4-
- [Install ESP32 Drivers](#install-esp32-drivers)
5+
- [Install ESP32 Drivers](#install-esp32-drivers)
56
- [Option 1: Arduino IDE](#option-1-arduino-ide)
6-
- [Install Arduino IDE](#install-arduino-ide)
7-
- [Install ESP32 Board Support](#install-esp32-board-support)
8-
- [Install Required Libraries](#install-required-libraries)
9-
- [Opening the Project](#opening-the-project-arduino-ide)
10-
- [Building the Project](#building-the-project-arduino-ide)
11-
- [Uploading to the ESP32](#uploading-to-the-esp32-arduino-ide)
7+
- [Install Arduino IDE](#install-arduino-ide)
8+
- [Install ESP32 Board Support](#install-esp32-board-support)
9+
- [Install Required Libraries](#install-required-libraries)
10+
- [Opening the Project (Arduino IDE)](#opening-the-project-arduino-ide)
11+
- [Building the Project (Arduino IDE)](#building-the-project-arduino-ide)
12+
- [Uploading to the ESP32 (Arduino IDE)](#uploading-to-the-esp32-arduino-ide)
1213
- [Option 2: PlatformIO](#option-2-platformio)
13-
- [Install PlatformIO](#install-platformio)
14-
- [Opening the Project](#opening-the-project-platformio)
15-
- [Building the Project](#building-the-project-platformio)
16-
- [Uploading to the ESP32](#uploading-to-the-esp32-platformio)
17-
- [PlatformIO Specific Notes](#platformio-specific-notes)
14+
- [Install PlatformIO](#install-platformio)
15+
- [Opening the Project (PlatformIO)](#opening-the-project-platformio)
16+
- [Building the Project (PlatformIO)](#building-the-project-platformio)
17+
- [Uploading to the ESP32 (PlatformIO)](#uploading-to-the-esp32-platformio)
18+
- [PlatformIO Specific Notes](#platformio-specific-notes)
1819
- [Additional Notes](#additional-notes)
1920

20-
21-
22-
2321
## Prerequisites
2422

2523
### Install ESP32 Drivers
@@ -31,7 +29,6 @@
3129
- **Windows:** Check the Device Manager for the COM port associated with your ESP32.
3230
- **macOS/Linux:** Verify the presence of `/dev/tty.*` devices corresponding to your ESP32.
3331

34-
3532
## Option 1: Arduino IDE
3633

3734
### Install Arduino IDE
@@ -58,14 +55,12 @@
5855
### Install Required Libraries
5956

6057
1. **Install EspSoftwareSerial:**
61-
6258
- Navigate to `Sketch` > `Include Library` > `Manage Libraries`.
6359
- In the **Library Manager** window, enter **"EspSoftwareSerial"** into the search bar.
6460
- Locate the **EspSoftwareSerial** library in the search results.
6561
- Click the **Install** button to add the library to your Arduino environment.
6662

6763
2. **Install DRA818:**
68-
6964
> **Note:** The version of the DRA818 library available through the Arduino Library Manager is currently broken. To ensure proper functionality, you need to install it manually from the official GitHub release.
7065
7166
- **Download the DRA818 Library ZIP:**
@@ -80,8 +75,7 @@
8075
- A confirmation message should appear indicating that the library was added successfully.
8176

8277
3. **Confirm All Libraries Are Installed:**
83-
84-
- After completing the above steps, ensure that both **EspSoftwareSerial** and **DRA818** are listed under `Sketch` > `Include Library`.
78+
- After completing the above steps, ensure that **EspSoftwareSerial** and **DRA818** are listed under `Sketch` > `Include Library`.
8579
- If any libraries are missing, revisit the installation steps to ensure they were added correctly.
8680

8781
### Opening the Project (Arduino IDE)
@@ -111,7 +105,6 @@
111105
- The Arduino IDE will compile (if not already done) and upload the firmware to the ESP32.
112106
- Monitor the output pane for upload progress and confirmation of success.
113107

114-
115108
## Option 2: PlatformIO
116109

117110
### Install PlatformIO
@@ -174,13 +167,12 @@
174167
### PlatformIO Specific Notes
175168

176169
- **Renaming the Main File for IntelliSense:**
177-
- **For IntelliSense to work properly in PlatformIO**, rename the main project file from `.ino` to `.cpp`. For example, rename `kv4p_ht_esp32_wroom_32.ino` to `kv4p_ht_esp32_wroom_32.cpp`.
178-
- **Important:** Do **not** commit this renamed file to the repository. Keeping the file as `.ino` in the repository ensures compatibility with the Arduino IDE build process.
179-
- **Workflow Suggestion:**
180-
- When working locally in PlatformIO, perform the rename to benefit from IntelliSense.
181-
- Before committing changes, revert the file extension back to `.ino` to maintain Arduino IDE compatibility.
182-
183-
170+
- ~~**For IntelliSense to work properly in PlatformIO**, rename the main project file from `.ino` to `.cpp`. For example, rename `kv4p_ht_esp32_wroom_32.ino` to `kv4p_ht_esp32_wroom_32.cpp`.~~
171+
- I don't think this is necessary anymore. My (@SmittyHalibut) PlatformIO does all the right things just editing a .ino file now (Jan 2025).
172+
- **Important:** Do **not** commit this renamed file to the repository. Keeping the file as `.ino` in the repository ensures compatibility with the Arduino IDE build process.
173+
- **Workflow Suggestion:**
174+
- When working locally in PlatformIO, perform the rename to benefit from IntelliSense.
175+
- Before committing changes, revert the file extension back to `.ino` to maintain Arduino IDE compatibility.
184176

185177
## Additional Notes
186178

@@ -194,7 +186,3 @@
194186

195187
- **Consistent Project Structure:**
196188
- Ensure that any changes made in one environment (e.g., library installations, code modifications) are compatible with the other to maintain consistency across both build systems.
197-
198-
199-
200-

microcontroller-src/kv4p_ht_esp32_wroom_32/kv4p_ht_esp32_wroom_32.ino

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ int matchedDelimiterTokens = 0;
5757
int matchedDelimiterTokensRx = 0;
5858

5959
// Mode of the app, which is essentially a state machine
60-
#define MODE_TX 0
61-
#define MODE_RX 1
62-
#define MODE_STOPPED 2
63-
int mode = MODE_STOPPED;
60+
enum Mode {
61+
MODE_TX,
62+
MODE_RX,
63+
MODE_STOPPED
64+
};
65+
Mode mode = MODE_STOPPED;
6466

6567
// Audio sampling rate, must match what Android app expects (and sends).
6668
#define AUDIO_SAMPLE_RATE 22050
@@ -116,6 +118,9 @@ char radioModuleStatus = RADIO_MODULE_NOT_FOUND;
116118
// Have we installed an I2S driver at least once?
117119
bool i2sStarted = false;
118120

121+
// Current SQ status
122+
bool squelched = false;
123+
119124
// I2S audio sampling stuff
120125
#define I2S_READ_LEN 1024/4
121126
#define I2S_WRITE_LEN 1024/4
@@ -138,6 +143,22 @@ typedef uint8_t hw_ver_t; // This allows us to do a lot more in the future if w
138143
// #define HW_VER_?? (0x0F) // Unused
139144
hw_ver_t hardware_version = HW_VER_V1; // lowest common denominator
140145

146+
// NeoPixel support
147+
#define PIXELS_PIN 13
148+
#define NUM_PIXELS 1
149+
150+
struct RGBColor {
151+
uint8_t red;
152+
uint8_t green;
153+
uint8_t blue;
154+
};
155+
const RGBColor COLOR_STOPPED = {0, 0, 0};
156+
const RGBColor COLOR_RX_SQL_CLOSED = {0, 0, 32};
157+
const RGBColor COLOR_RX_SQL_OPEN = {0, 32, 0};
158+
const RGBColor COLOR_TX = {16, 16, 0};
159+
const RGBColor COLOR_BLACK = {0, 0, 0};
160+
RGBColor COLOR_HW_VER = COLOR_BLACK;
161+
141162
#define _LOGE(fmt, ...) \
142163
{ \
143164
debug_log_printf(COMMAND_DEBUG_ERROR, ARDUHAL_LOG_FORMAT(E, fmt), ##__VA_ARGS__); \
@@ -166,11 +187,13 @@ hw_ver_t hardware_version = HW_VER_V1; // lowest common denominator
166187
void initI2SRx();
167188
void initI2STx();
168189
void tuneTo(float freqTx, float freqRx, int tone, int squelch, String bandwidth);
169-
void setMode(int newMode);
190+
void setMode(Mode newMode);
170191
void processTxAudio(uint8_t tempBuffer[], int bytesRead);
171192
void iir_lowpass_reset();
172193
hw_ver_t get_hardware_version();
173194
void reportPhysPttState();
195+
void show_LEDs();
196+
void neopixelColor(RGBColor C, uint8_t bright);
174197

175198
void sendCmdToAndroid(byte cmdByte, const byte *params, size_t paramsLen);
176199

@@ -211,16 +234,20 @@ void setup() {
211234
// Hardware dependent pin assignments.
212235
switch (hardware_version) {
213236
case HW_VER_V1:
237+
COLOR_HW_VER = {0, 32, 0};
214238
SQ_PIN = 32;
215239
break;
216240
case HW_VER_V2_0C:
241+
COLOR_HW_VER = {32, 0, 0};
217242
SQ_PIN = 4;
218243
break;
219244
case HW_VER_V2_0D:
245+
COLOR_HW_VER = {0, 0, 32};
220246
SQ_PIN = 4;
221247
break;
222248
default:
223249
// Unknown version detected. Indicate this some way?
250+
COLOR_HW_VER = {16, 16, 16};
224251
break;
225252
}
226253

@@ -249,7 +276,9 @@ void setup() {
249276

250277
printEnvironment();
251278
// Begin in STOPPED mode
279+
squelched = (digitalRead(SQ_PIN) == HIGH);
252280
setMode(MODE_STOPPED);
281+
show_LEDs();
253282
_LOGI("Setup is finished");
254283
}
255284

@@ -424,7 +453,7 @@ void loop() {
424453

425454
if (hardware_version == HW_VER_V2_0C) {
426455
// v2.0c has a lower input ADC range.
427-
result = dra->volume(4);
456+
result = dra->volume(6);
428457
} else {
429458
result = dra->volume(8);
430459
}
@@ -654,7 +683,7 @@ void loop() {
654683
ESP_ERROR_CHECK(i2s_read(I2S_NUM_0, &buffer16, sizeof(buffer16), &bytesRead, 0));
655684
size_t samplesRead = bytesRead / 2;
656685

657-
bool squelched = (digitalRead(SQ_PIN) == HIGH);
686+
squelched = (digitalRead(SQ_PIN) == HIGH);
658687

659688
for (int i = 0; i < samplesRead; i++) {
660689
int16_t sample = remove_dc(2048 - (int16_t)(buffer16[i] & 0xfff));
@@ -734,6 +763,7 @@ void loop() {
734763
// Disregard, we don't want to crash. Just pick up at next loop().)
735764
// Serial.println("Exception in loop(), skipping cycle.");
736765
}
766+
show_LEDs();
737767
}
738768

739769
/**
@@ -775,25 +805,22 @@ void tuneTo(float freqTx, float freqRx, int txTone, int rxTone, int squelch, Str
775805
// Serial.println("tuneTo: " + String(result));
776806
}
777807

778-
void setMode(int newMode) {
808+
void setMode(Mode newMode) {
779809
mode = newMode;
780810
switch (mode) {
781811
case MODE_STOPPED:
782812
_LOGI("MODE_STOPPED");
783-
digitalWrite(LED_PIN, LOW);
784813
digitalWrite(PTT_PIN, HIGH);
785814
break;
786815
case MODE_RX:
787816
_LOGI("MODE_RX");
788-
digitalWrite(LED_PIN, LOW);
789817
digitalWrite(PTT_PIN, HIGH);
790818
initI2SRx();
791819
matchedDelimiterTokensRx = 0;
792820
break;
793821
case MODE_TX:
794822
_LOGI("MODE_TX");
795823
txStartTime = micros();
796-
digitalWrite(LED_PIN, HIGH);
797824
digitalWrite(PTT_PIN, LOW);
798825
initI2STx();
799826
txCachedAudioBytes = 0;
@@ -874,3 +901,51 @@ void measureLoopFrequency() {
874901
lastTime = now;
875902
}
876903
}
904+
905+
void neopixelColor(RGBColor C, uint8_t bright = 255) {
906+
uint8_t red = (uint16_t(C.red) * bright) / 255;
907+
uint8_t green = (uint16_t(C.green) * bright) / 255;
908+
uint8_t blue = (uint16_t(C.blue) * bright) / 255;
909+
neopixelWrite(PIXELS_PIN, red, green, blue);
910+
}
911+
912+
// Calculate a float between min and max, that ramps from min to max in half of breath_every,
913+
// and from max to min the second half of breath_every.
914+
// now and breath_every are arbitrary units, but usually are milliseconds from millis().
915+
uint8_t calc_breath(uint32_t now, uint32_t breath_every, uint8_t min, uint8_t max) {
916+
uint16_t amplitude = max - min; // Ensure enough range for calculations
917+
uint16_t bright = ((now % breath_every) * 512) / breath_every; // Scale to 0-512
918+
if (bright > 255) bright = 512 - bright; // Fold >255 back down to 255-0
919+
return ((bright * amplitude) / 255) + min;
920+
}
921+
922+
void show_LEDs() {
923+
// When to actually act?
924+
static uint32_t next_time = 0;
925+
const static uint32_t update_every = 50; // in milliseconds
926+
uint32_t now = millis();
927+
// Only change LEDs if:
928+
// * it's been more than update_every ms since we've last set the LEDs.
929+
if (now >= next_time) {
930+
next_time = now + update_every;
931+
switch (mode) {
932+
case MODE_STOPPED:
933+
digitalWrite(LED_PIN, LOW);
934+
neopixelColor(COLOR_HW_VER);
935+
break;
936+
case MODE_RX:
937+
digitalWrite(LED_PIN, LOW);
938+
if (squelched) {
939+
neopixelColor(COLOR_RX_SQL_CLOSED, calc_breath(now, 2000, 127, 255));
940+
} else {
941+
neopixelColor(COLOR_RX_SQL_OPEN);
942+
}
943+
break;
944+
case MODE_TX:
945+
digitalWrite(LED_PIN, HIGH);
946+
neopixelColor(COLOR_TX);
947+
break;
948+
}
949+
}
950+
}
951+

website-src/contribute.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@ <h1>Overview docs</h1>
7575
</main>
7676
</div>
7777
</body>
78-
</html>
78+
</html>

0 commit comments

Comments
 (0)