Description:
Transmits fixed-code SubGHz Flipper Zero raw signals. Based on the ESP32 microcontroller and CC1101 transceiver.
#include <Adafruit_NeoPixel.h> | |
#include "driver/rtc_io.h" | |
#include <ELECHOUSE_CC1101_SRC_DRV.h> | |
//SPI Connection | |
byte sck = 5; | |
byte miso = 21; | |
byte mosi = 19; | |
byte ss = 33; | |
//TX & RX Pins | |
#define GDO0 32 | |
#define GDO2 4 | |
//Button | |
#define btn 38 | |
//Battery Voltage Pin | |
#define VBATPIN 35 | |
//Neopixel Config | |
#define neoPixelPin 0 | |
#define numPixels 1 | |
Adafruit_NeoPixel pixels(numPixels, neoPixelPin, NEO_GRB + NEO_KHZ800); | |
int rawRecording[] = { -5000, 1000, -5000, 1000, -2000, 1000, -5000, 1000, -5000, 1000, | |
-8000, 1000, -5000, 1000, -5000, 1000, -2000, 1000, -5000, 1000, -5000, 1000, | |
-8000, 1000, -5000, 1000, -5000, 1000, -5000, 1000, -2000, 1000, -5000, 1000, -5000, 1000, | |
-8000, 1000, -2000, 1000, -8000, 1000, -2000, 1000, -8000, 1000, -2000, 1000, -9000, | |
-5000, 1000, -5000, 1000, -2000, 1000, -5000, 1000, -5000, 1000, | |
-8000, 1000, -5000, 1000, -5000, 1000, -2000, 1000, -5000, 1000, -5000, 1000, | |
-8000, 1000, -5000, 1000, -5000, 1000, -5000, 1000, -2000, 1000, -5000, 1000, -5000, 1000, | |
-8000, 1000, -2000, 1000, -8000, 1000, -2000, 1000, -8000, 1000, -2000, 1000, -9000 }; | |
int lengthOfRec = sizeof(rawRecording) / sizeof(rawRecording[0]); | |
void initCC1101(float mhz) { | |
ELECHOUSE_cc1101.setSpiPin(sck, miso, mosi, ss); //Set custom SPI pins | |
ELECHOUSE_cc1101.setGDO(GDO0, GDO2); //Set custom GDO0 GDO2 pins | |
ELECHOUSE_cc1101.Init(); | |
ELECHOUSE_cc1101.setClb(1, 0, 0); | |
ELECHOUSE_cc1101.setMHZ(mhz); | |
ELECHOUSE_cc1101.SetTx(); | |
ELECHOUSE_cc1101.setModulation(2); // OOK modulation | |
ELECHOUSE_cc1101.setDRate(2.4); // Set data rate to 2.4 kBaud | |
ELECHOUSE_cc1101.setPktFormat(3); // Asynchronous serial mode | |
ELECHOUSE_cc1101.setPA(10); // Set TxPower | |
if (ELECHOUSE_cc1101.getCC1101()) { // Check the CC1101 Spi connection. | |
Serial.println("Connection OK"); | |
} else { | |
Serial.println("Connection Error"); | |
} | |
} | |
void sendSamples(int rawRecording[], int arrayLength) { | |
Serial.println("Starting Transmission of " + String(arrayLength) + " samples"); | |
for (int i = 0; i < arrayLength; i++) { | |
bool txState; | |
int timing = abs(rawRecording[i]); | |
if (rawRecording[i] > 0) { | |
txState = HIGH; | |
} else { | |
txState = LOW; | |
} | |
digitalWrite(GDO0, txState); | |
delayMicroseconds(timing); | |
} | |
Serial.println("Transmission Completed"); | |
digitalWrite(GDO0, LOW); | |
ELECHOUSE_cc1101.goSleep(); | |
} | |
double readBattery() { | |
float measuredvbat = analogReadMilliVolts(VBATPIN); | |
measuredvbat *= 2; // we divided by 2, so multiply back | |
measuredvbat /= 1000; // convert to volts! | |
double batteryPercentage = 105 - (105 / (1 + pow(1.724 * (measuredvbat - 3.2) / (4.2 - 3.2), 5.5))); | |
Serial.print("Battery voltage is "); | |
Serial.print(measuredvbat); | |
Serial.print(" ("); | |
Serial.print(batteryPercentage); | |
Serial.println("%)"); | |
return batteryPercentage; | |
} | |
void controlNeoPixel(double percentage) { | |
pixels.begin(); | |
pixels.setBrightness(80); | |
if (percentage > 10.0) { | |
// Turn NeoPixel green | |
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // Green | |
} else { | |
// Turn NeoPixel red | |
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red | |
Serial.println("Battery Low"); | |
} | |
pixels.show(); | |
// Keep the NeoPixel on for 2 seconds | |
delay(2000); | |
// Turn off the NeoPixel | |
pixels.clear(); | |
pixels.show(); | |
} | |
void setup() { | |
Serial.begin(115200); | |
// Pin Setup | |
pinMode(GDO0, OUTPUT); | |
pinMode(btn, INPUT); | |
pinMode(VBATPIN, INPUT); | |
// Deep Sleep Setup | |
esp_sleep_enable_ext0_wakeup(GPIO_NUM_38, LOW); | |
rtc_gpio_pullup_dis(GPIO_NUM_38); | |
rtc_gpio_pulldown_en(GPIO_NUM_38); | |
// Initialize CC1101 | |
initCC1101(318); | |
// Handle Transmission and Battery Management | |
sendSamples(rawRecording, lengthOfRec); | |
double batteryPercentage = readBattery(); | |
controlNeoPixel(batteryPercentage); | |
Serial.println("Entering deep sleep..."); | |
esp_deep_sleep_start(); // ESP32 will enter deep sleep here | |
} | |
void loop() { | |
} |