Skip to content

Instantly share code, notes, and snippets.

@xssfox
Last active January 4, 2022 18:12
Show Gist options
  • Save xssfox/de5f599e12176a2f1a92a48b24d4fed2 to your computer and use it in GitHub Desktop.
Save xssfox/de5f599e12176a2f1a92a48b24d4fed2 to your computer and use it in GitHub Desktop.
Control a NodeMCU semi-securely over radio (rename to .ino)
/*
Built for NodeMCU ESP32
You'll need
NTPClient : https://www.arduino.cc/reference/en/libraries/ntpclient/
PhoneDTFM : https://github.com/Adrianotiger/phoneDTMF
TOTP : https://www.arduino.cc/reference/en/libraries/totp-library/
For connecting a baofeng UV-5R I used the kenwood connector and this circuit to remove any bias
from the baofeng and decouple then used the resistors to center the signal for the NodeMCU.
I then adjusted the volume on the UV-5R until vMax was ~3v when squelch is open to noise.
THIS IS NOT THE BEST CIRCUIT - JUST ONE THAT WORKS FOR THE PROTOTYPE.
BE CAREFUL NOT TO EXCEED 3.3V to the NodeMCU
|----------- 3.3v
|
(R 2K)
|
spkr+ ----(C 470nF)------------- D34
|
(R 2K)
|
spkr- ------------------------- gnd
*/
#include <WiFi.h>
#include <TOTP.h>
#include <sha1.h>
#include <NTPClient.h>
#include <driver/adc.h>
#include <PhoneDTMF.h>
#define LED 2
char ssid[] = "";
char password[] = "";
PhoneDTMF dtmf = PhoneDTMF();
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
bool ledStatus = false;
#define RESET_TIME 20
#define INTER_TIME 3
int resetTime = 0;
bool readyDTMF = true;
uint8_t hmacKey[] = {0x4d, 0x79, 0x4c, 0x65, 0x67, 0x6f, 0x44, 0x6f, 0x6f, 0x72}; // for auth apps you'll need to base32 this.
TOTP totp = TOTP(hmacKey, 10);
void setup() {
adc1_config_width(ADC_WIDTH_BIT_12); // set 12 bit (0-4096)
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
dtmf.begin(34);
pinMode(LED,OUTPUT);
Serial.begin(9600);
while (!Serial);
Serial.println("TOTP demo");
Serial.println();
// connect to the WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Establishing connection to WiFi...");
}
Serial.print("Connected to WiFi with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
// start the NTP client
timeClient.begin();
Serial.println("NTP client started");
Serial.println();
}
String totpCode = String("");
String dtmfCode = String("");
void loop() {
// put your main code here, to run repeatedly:
resetTime = resetTime - 1;
if (resetTime == 0){
Serial.println("Timed out");
dtmfCode = "";
readyDTMF = true;
}
uint8_t tones = dtmf.detect();
char button = dtmf.tone2char(tones);
if (button > 0) {
resetTime = RESET_TIME;
if (readyDTMF == true){
dtmfCode += button;
Serial.println(dtmfCode);
readyDTMF = false;
}
}
if (RESET_TIME - resetTime > INTER_TIME){
readyDTMF = true;
}
timeClient.update();
String newCode = String(totp.getCode(timeClient.getEpochTime()));
if (totpCode != newCode) {
totpCode = String(newCode);
Serial.print("TOTP code: ");
Serial.println(newCode);
}
if (
dtmfCode == String(totp.getCode(timeClient.getEpochTime())) ||
dtmfCode == String(totp.getCode(timeClient.getEpochTime()-30)) ||
dtmfCode == String(totp.getCode(timeClient.getEpochTime()-60)) ||
dtmfCode == String(totp.getCode(timeClient.getEpochTime()-120))
) {
Serial.println("Correct code!");
if (ledStatus == true){
ledStatus = false;
digitalWrite(LED,LOW);
} else {
ledStatus = true;
digitalWrite(LED,HIGH);
}
resetTime = 0;
readyDTMF = true;
dtmfCode = String();
}
//Serial.println(analogRead(34));
delay(100);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment