initial commit

This commit is contained in:
krolyxon 2026-05-04 22:48:07 +05:30
commit 0a40daf4fa
30 changed files with 3228 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
schmatics
documentation
# Clangd cache
.cache

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,194 @@
/*
ELECHOUSE_CC1101.cpp - CC1101 module library
Copyright (c) 2010 Michael.
Author: Michael, <www.elechouse.com>
Version: November 12, 2010
This library is designed to use CC1101/CC1100 module on Arduino platform.
CC1101/CC1100 module is an useful wireless module.Using the functions of the
library, you can easily send and receive data by the CC1101/CC1100 module.
Just have fun!
For the details, please refer to the datasheet of CC1100/CC1101.
----------------------------------------------------------------------------------------------------------------
cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE).
----------------------------------------------------------------------------------------------------------------
*/
#ifndef ELECHOUSE_CC1101_SRC_DRV_h
#define ELECHOUSE_CC1101_SRC_DRV_h
#include <Arduino.h>
//***************************************CC1101 define**************************************************//
// CC1101 CONFIG REGSITER
#define CC1101_IOCFG2 0x00 // GDO2 output pin configuration
#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration
#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration
#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
#define CC1101_SYNC1 0x04 // Sync word, high INT8U
#define CC1101_SYNC0 0x05 // Sync word, low INT8U
#define CC1101_PKTLEN 0x06 // Packet length
#define CC1101_PKTCTRL1 0x07 // Packet automation control
#define CC1101_PKTCTRL0 0x08 // Packet automation control
#define CC1101_ADDR 0x09 // Device address
#define CC1101_CHANNR 0x0A // Channel number
#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control
#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control
#define CC1101_FREQ2 0x0D // Frequency control word, high INT8U
#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U
#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U
#define CC1101_MDMCFG4 0x10 // Modem configuration
#define CC1101_MDMCFG3 0x11 // Modem configuration
#define CC1101_MDMCFG2 0x12 // Modem configuration
#define CC1101_MDMCFG1 0x13 // Modem configuration
#define CC1101_MDMCFG0 0x14 // Modem configuration
#define CC1101_DEVIATN 0x15 // Modem deviation setting
#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration
#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration
#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration
#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration
#define CC1101_BSCFG 0x1A // Bit Synchronization configuration
#define CC1101_AGCCTRL2 0x1B // AGC control
#define CC1101_AGCCTRL1 0x1C // AGC control
#define CC1101_AGCCTRL0 0x1D // AGC control
#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout
#define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout
#define CC1101_WORCTRL 0x20 // Wake On Radio control
#define CC1101_FREND1 0x21 // Front end RX configuration
#define CC1101_FREND0 0x22 // Front end TX configuration
#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration
#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration
#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration
#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration
#define CC1101_RCCTRL1 0x27 // RC oscillator configuration
#define CC1101_RCCTRL0 0x28 // RC oscillator configuration
#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control
#define CC1101_PTEST 0x2A // Production test
#define CC1101_AGCTEST 0x2B // AGC test
#define CC1101_TEST2 0x2C // Various test settings
#define CC1101_TEST1 0x2D // Various test settings
#define CC1101_TEST0 0x2E // Various test settings
//CC1101 Strobe commands
#define CC1101_SRES 0x30 // Reset chip.
#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
// If in RX/TX: Go to a wait state where only the synthesizer is
// running (for quick RX / TX turnaround).
#define CC1101_SXOFF 0x32 // Turn off crystal oscillator.
#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
// (enables quick start).
#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
// MCSM0.FS_AUTOCAL=1.
#define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
// Only go to TX if channel is clear.
#define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
// Wake-On-Radio mode if applicable.
#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high.
#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer.
#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer.
#define CC1101_SWORRST 0x3C // Reset real time clock.
#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two
// INT8Us for simpler software.
//CC1101 STATUS REGSITER
#define CC1101_PARTNUM 0x30
#define CC1101_VERSION 0x31
#define CC1101_FREQEST 0x32
#define CC1101_LQI 0x33
#define CC1101_RSSI 0x34
#define CC1101_MARCSTATE 0x35
#define CC1101_WORTIME1 0x36
#define CC1101_WORTIME0 0x37
#define CC1101_PKTSTATUS 0x38
#define CC1101_VCO_VC_DAC 0x39
#define CC1101_TXBYTES 0x3A
#define CC1101_RXBYTES 0x3B
//CC1101 PATABLE,TXFIFO,RXFIFO
#define CC1101_PATABLE 0x3E
#define CC1101_TXFIFO 0x3F
#define CC1101_RXFIFO 0x3F
//************************************* class **************************************************//
class ELECHOUSE_CC1101
{
private:
void SpiStart(void);
void SpiEnd(void);
void GDO_Set (void);
void GDO0_Set (void);
void Reset (void);
void setSpi(void);
void RegConfigSettings(void);
void Calibrate(void);
void Split_PKTCTRL0(void);
void Split_PKTCTRL1(void);
void Split_MDMCFG1(void);
void Split_MDMCFG2(void);
void Split_MDMCFG4(void);
public:
void Init(void);
byte SpiReadStatus(byte addr);
void setSpiPin(byte sck, byte miso, byte mosi, byte ss);
void addSpiPin(byte sck, byte miso, byte mosi, byte ss, byte modul);
void setGDO(byte gdo0, byte gdo2);
void setGDO0(byte gdo0);
void addGDO(byte gdo0, byte gdo2, byte modul);
void addGDO0(byte gdo0, byte modul);
void setModul(byte modul);
void setCCMode(bool s);
void setModulation(byte m);
void setPA(int p);
void setMHZ(float mhz);
void setChannel(byte chnl);
void setChsp(float f);
void setRxBW(float f);
void setDRate(float d);
void setDeviation(float d);
void SetTx(void);
void SetRx(void);
void SetTx(float mhz);
void SetRx(float mhz);
int getRssi(void);
byte getLqi(void);
void setSres(void);
void setSidle(void);
void goSleep(void);
void SendData(byte *txBuffer, byte size);
void SendData(char *txchar);
void SendData(byte *txBuffer, byte size, int t);
void SendData(char *txchar, int t);
byte CheckReceiveFlag(void);
byte ReceiveData(byte *rxBuffer);
bool CheckCRC(void);
void SpiStrobe(byte strobe);
void SpiWriteReg(byte addr, byte value);
void SpiWriteBurstReg(byte addr, byte *buffer, byte num);
byte SpiReadReg(byte addr);
void SpiReadBurstReg(byte addr, byte *buffer, byte num);
void setClb(byte b, byte s, byte e);
bool getCC1101(void);
byte getMode(void);
void setSyncWord(byte sh, byte sl);
void setAddr(byte v);
void setWhiteData(bool v);
void setPktFormat(byte v);
void setCrc(bool v);
void setLengthConfig(byte v);
void setPacketLength(byte v);
void setDcFilterOff(bool v);
void setManchester(bool v);
void setSyncMode(byte v);
void setFEC(bool v);
void setPRE(byte v);
void setPQT(byte v);
void setCRC_AF(bool v);
void setAppendStatus(bool v);
void setAdrChk(byte v);
bool CheckRxFifo(int t);
};
extern ELECHOUSE_CC1101 ELECHOUSE_cc1101;
#endif

56
firmware/badusb.cpp Normal file
View File

@ -0,0 +1,56 @@
#include <Arduino.h>
#include <USBHIDKeyboard.h>
extern USBHIDKeyboard Keyboard;
void runBadUSBDemo()
{
delay(2000);
Keyboard.println("");
Keyboard.println("#-FEATURES:");
Keyboard.println("1- WIFI ATTACKS");
Keyboard.println("2- BLE ATTACKS");
Keyboard.println("3- BAD USB");
Keyboard.println("4- NFC");
Keyboard.println("5- INFRARED");
Keyboard.println("6- SUB-GHZ");
Keyboard.println("7- GPIO");
Keyboard.println("8- APPS");
Keyboard.println("9- SETTINGS");
Keyboard.println("10- FILES");
}
void runBadUSBOpenCMD()
{
delay(2000);
Keyboard.println("");
Keyboard.println("#-FEATURES:");
Keyboard.println("1- WIFI ATTACKS");
Keyboard.println("2- BLE ATTACKS");
Keyboard.println("3- BAD USB");
Keyboard.println("4- NFC");
Keyboard.println("5- INFRARED");
Keyboard.println("6- SUB-GHZ");
Keyboard.println("7- GPIO");
Keyboard.println("8- APPS");
Keyboard.println("9- SETTINGS");
Keyboard.println("10- FILES");
}
void runBadUSBRickroll()
{
delay(2000);
Keyboard.println("");
Keyboard.println("#-FEATURES:");
Keyboard.println("1- WIFI ATTACKS");
Keyboard.println("2- BLE ATTACKS");
Keyboard.println("3- BAD USB");
Keyboard.println("4- NFC");
Keyboard.println("5- INFRARED");
Keyboard.println("6- SUB-GHZ");
Keyboard.println("7- GPIO");
Keyboard.println("8- APPS");
Keyboard.println("9- SETTINGS");
Keyboard.println("10- FILES");
}

5
firmware/badusb.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void runBadUSBDemo();
void runBadUSBOpenCMD();
void runBadUSBRickroll();

211
firmware/blescanner.cpp Normal file
View File

@ -0,0 +1,211 @@
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <vector>
#include "display.h"
#include "buttons.h"
#include "config.h"
// ===== DEVICE STRUCT =====
struct BLEDeviceInfo {
String name;
String address;
int rssi;
String manufacturer;
String deviceType;
};
static std::vector<BLEDeviceInfo> devices;
static BLEScan *pBLEScan;
static int selectedIndex = 0;
// ===== CALLBACK =====
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) override {
BLEDeviceInfo dev;
String tempName = advertisedDevice.getName();
if (tempName.length() == 0 && advertisedDevice.haveServiceData()) {
tempName = advertisedDevice.getServiceData().c_str();
}
if (tempName.length() == 0) {
String addr = advertisedDevice.getAddress().toString().c_str();
tempName = "BLE_" + addr.substring(addr.length() - 5);
}
dev.name = tempName;
dev.address = advertisedDevice.getAddress().toString().c_str();
dev.rssi = advertisedDevice.getRSSI();
if (advertisedDevice.haveManufacturerData()) {
String mData = advertisedDevice.getManufacturerData().c_str();
if (mData.length() >= 2) {
char buffer[10];
sprintf(buffer, "0x%02X%02X",
(uint8_t)mData[1],
(uint8_t)mData[0]);
dev.manufacturer = String(buffer);
} else {
dev.manufacturer = "unknown";
}
} else {
dev.manufacturer = "unknown";
}
if (advertisedDevice.haveServiceUUID()) {
dev.deviceType =
advertisedDevice.getServiceUUID().toString().c_str();
} else {
dev.deviceType = "unknown";
}
devices.push_back(dev);
}
};
// ===== DRAW MENU =====
void ble_drawMenu()
{
u8g2.clearBuffer();
if (devices.empty())
{
u8g2.setFont(u8g2_font_6x12_tr);
u8g2.drawStr(0, 30, "No devices");
u8g2.drawStr(0, 45, "Press BACK");
}
else
{
u8g2.setFont(u8g2_font_5x8_tr);
char counter[20];
sprintf(counter, "%d/%d", selectedIndex + 1, (int)devices.size());
u8g2.drawStr(0, 8, counter);
u8g2.setFont(u8g2_font_6x10_tr);
for (int i = 0; i < 3; i++)
{
int idx = selectedIndex + i;
if (idx >= devices.size()) break;
int y = 22 + i * 14;
if (i == 0)
{
u8g2.drawBox(0, y - 10, 128, 12);
u8g2.setDrawColor(0);
}
String text = devices[idx].name;
if (text.length() > 12)
text = text.substring(0, 12) + "..";
text += " (" + String(devices[idx].rssi) + ")";
u8g2.drawStr(2, y, text.c_str());
if (i == 0)
u8g2.setDrawColor(1);
}
}
u8g2.sendBuffer();
}
// ===== DEVICE DETAILS =====
void ble_drawDetails(const BLEDeviceInfo &dev)
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tr);
u8g2.drawStr(0, 10, dev.name.c_str());
u8g2.drawStr(0, 20, dev.address.c_str());
char rssiStr[20];
sprintf(rssiStr, "RSSI: %d", dev.rssi);
u8g2.drawStr(0, 30, rssiStr);
u8g2.drawStr(0, 40, dev.manufacturer.c_str());
u8g2.sendBuffer();
}
// ===== SCAN =====
void ble_scan()
{
devices.clear();
u8g2.clearBuffer();
u8g2.drawStr(10, 30, "Scanning...");
u8g2.sendBuffer();
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
pBLEScan->setActiveScan(true);
pBLEScan->setInterval(100);
pBLEScan->setWindow(99);
pBLEScan->start(5, false);
// remove duplicates
std::vector<BLEDeviceInfo> unique;
for (auto &d : devices)
{
bool exists = false;
for (auto &u : unique)
{
if (u.address == d.address)
{
exists = true;
break;
}
}
if (!exists) unique.push_back(d);
}
devices = unique;
}
// ===== MAIN LOOP =====
void ble_loop()
{
static uint32_t lastPress = 0;
if (millis() - lastPress < 200)
return;
if (btnDown() && selectedIndex < (int)devices.size() - 1)
{
selectedIndex++;
ble_drawMenu();
lastPress = millis();
}
else if (btnUp() && selectedIndex > 0)
{
selectedIndex--;
ble_drawMenu();
lastPress = millis();
}
else if (btnSelect() && !devices.empty())
{
ble_drawDetails(devices[selectedIndex]);
delay(3000);
ble_drawMenu();
lastPress = millis();
}
else if (btnBack())
{
ble_scan();
selectedIndex = 0;
ble_drawMenu();
lastPress = millis();
}
}

5
firmware/blescanner.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void ble_scan();
void ble_loop();
void ble_drawMenu();

20
firmware/buttons.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "buttons.h"
#include <Arduino.h>
#define BTN_UP 4
#define BTN_DOWN 5
#define BTN_SELECT 6
#define BTN_BACK 7
void buttonsInit()
{
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_SELECT, INPUT_PULLUP);
pinMode(BTN_BACK, INPUT_PULLUP);
}
bool btnUp() { return !digitalRead(BTN_UP); }
bool btnDown() { return !digitalRead(BTN_DOWN); }
bool btnSelect() { return !digitalRead(BTN_SELECT); }
bool btnBack() { return !digitalRead(BTN_BACK); }

8
firmware/buttons.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
void buttonsInit();
bool btnUp();
bool btnDown();
bool btnSelect();
bool btnBack();

150
firmware/cc1101.cpp Normal file
View File

@ -0,0 +1,150 @@
#include <Arduino.h>
#include "ELECHOUSE_CC1101_SRC_DRV.h"
#include "cc1101.h"
#include "config.h"
// ===== CONFIG =====
#define RAW_BUF_MAX 512
// ===== STATE =====
static bool cc1101Inited = false;
// ===== CAPTURE STATE =====
volatile unsigned long captureBuffer[RAW_BUF_MAX];
volatile int pulseIndex = 0;
volatile unsigned long lastEdgeTime = 0;
volatile bool capturing = false;
// ===== RF SETTINGS =====
float currentFreq = 433.92;
float dataRate = 3.79372;
float deviation = 0.0;
float rxBW = 325.0;
int powerLevel = 10;
// ===== ISR =====
void IRAM_ATTR pulseISR()
{
unsigned long now = micros();
if (!capturing) return;
if (pulseIndex >= RAW_BUF_MAX) return;
unsigned long duration = now - lastEdgeTime;
if (duration < 50) return;
captureBuffer[pulseIndex++] = duration;
lastEdgeTime = now;
}
// ===== OOK SETUP =====
void setupOOKMode()
{
ELECHOUSE_cc1101.SetRx();
ELECHOUSE_cc1101.setMHZ(currentFreq);
ELECHOUSE_cc1101.setModulation(0); // ASK/OOK
ELECHOUSE_cc1101.setDRate(dataRate);
ELECHOUSE_cc1101.setDeviation(0);
ELECHOUSE_cc1101.setRxBW(rxBW);
ELECHOUSE_cc1101.setSyncMode(0);
ELECHOUSE_cc1101.setPA(powerLevel);
}
// ===== INIT (LAZY, SAFE) =====
bool initCC1101()
{
if (cc1101Inited)
return true;
Serial.println("Initializing CC1101...");
// IMPORTANT: no detachInterrupt here (causes crash if not installed)
ELECHOUSE_cc1101.setSpiPin(
cc1101_SCK,
cc1101_MISO,
cc1101_MOSI,
CC1101_CS
);
ELECHOUSE_cc1101.setGDO(CC1101_GDO0, CC1101_GDO2);
if (!ELECHOUSE_cc1101.getCC1101())
{
Serial.println("❌ CC1101 NOT FOUND");
return false;
}
delay(10); // let SPI settle
ELECHOUSE_cc1101.Init(); // THIS WAS YOUR FREEZE POINT
setupOOKMode();
pinMode(CC1101_GDO0, INPUT);
Serial.println("✅ CC1101 READY");
cc1101Inited = true;
return true;
}
// ===== CAPTURE CONTROL =====
void startCapture()
{
pulseIndex = 0;
capturing = true;
lastEdgeTime = micros();
attachInterrupt(
digitalPinToInterrupt(CC1101_GDO0),
pulseISR,
CHANGE
);
Serial.println("Capture started");
}
bool isCC1101Ready() {
return cc1101Inited;
}
void stopCapture()
{
capturing = false;
detachInterrupt(digitalPinToInterrupt(CC1101_GDO0));
Serial.println("Capture stopped");
}
// ===== DEBUG PRINT =====
void printCapture()
{
Serial.println("Captured pulses:");
for (int i = 0; i < pulseIndex; i++)
{
Serial.println(captureBuffer[i]);
}
}
// ===== REPLAY =====
void replaySignal()
{
Serial.println("Replaying...");
ELECHOUSE_cc1101.SetTx();
pinMode(CC1101_GDO0, OUTPUT);
for (int i = 0; i < pulseIndex; i++)
{
digitalWrite(CC1101_GDO0, (i % 2 == 0) ? HIGH : LOW);
delayMicroseconds(captureBuffer[i]);
}
digitalWrite(CC1101_GDO0, LOW);
ELECHOUSE_cc1101.SetRx();
}

9
firmware/cc1101.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
bool initCC1101();
bool isCC1101Ready();
void startCapture();
void stopCapture();
void printCapture();
void replaySignal();

48
firmware/config.h Normal file
View File

@ -0,0 +1,48 @@
#pragma once
// ================= NRF24 =================
#define CE1_PIN 10
#define CSN1_PIN 11
#define CE2_PIN 12
#define CSN2_PIN 13
#define NRF_SCK 18
#define NRF_MISO 16
#define NRF_MOSI 17
// ================== OLED ===================
#define OLED_SDA_PIN 8
#define OLED_SCL_PIN 9
/////////////////cc1101 vars//////////////
// CC1101 via FSPI
#define cc1101_SCK 15
#define cc1101_MISO 3
#define cc1101_MOSI 46
//////////////cc1101(1)//////////
#define CC1101_CS 45
#define CC1101_GDO0 21
#define CC1101_GDO2 47
/////////////cc1101(2)//////////
#define CC1101_2_CS 40
#define CC1101_2_GDO0 41
#define CC1101_2_GDO2 42
// SD Card via HSPI
#define SD_SCK 14
#define SD_MISO 39
#define SD_MOSI 38
#define SD_CS 37
// =================== Buttons ====================
#define BTN_UP 4
#define BTN_DOWN 5
#define BTN_SELECT 6
#define BTN_BACK 7
#define BTN_LEFT 1
#define BTN_RIGHT 2

Binary file not shown.

242
firmware/device_check.cpp Normal file
View File

@ -0,0 +1,242 @@
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <RF24.h>
#include "ELECHOUSE_CC1101_SRC_DRV.h"
#include "display.h"
#include "buttons.h"
#include "config.h"
// ===== EXTERNALS =====
extern RF24 radio1;
extern RF24 radio2;
extern SPIClass *RADIO_SPI;
extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2;
// ===== RESULTS =====
struct DeviceStatus {
bool nrf_link = false;
bool nrf1 = false;
bool nrf2 = false;
bool cc1101 = false;
bool oled = true;
bool buttons = false;
};
// ===== NRF CHECK =====
bool checkNRF(RF24 &radio)
{
// safer: only init if needed
if (!radio.isChipConnected()) {
if (!radio.begin(RADIO_SPI))
return false;
}
return radio.isChipConnected();
}
// ===== CC1101 CHECK =====
bool checkCC1101()
{
ELECHOUSE_cc1101.setSpiPin(
cc1101_SCK,
cc1101_MISO,
cc1101_MOSI,
CC1101_CS
);
delay(5); // important stabilization
return ELECHOUSE_cc1101.getCC1101();
}
// ===== BUTTON CHECK =====
bool checkButtons()
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tr);
u8g2.drawStr(0, 20, "Press any button...");
u8g2.sendBuffer();
unsigned long start = millis();
while (millis() - start < 2000)
{
if (!digitalRead(BTN_UP) ||
!digitalRead(BTN_DOWN) ||
!digitalRead(BTN_SELECT) ||
!digitalRead(BTN_BACK))
{
return true;
}
}
return false;
}
// ===== DRAW =====
#define MAX_ITEMS 6
#define VISIBLE_ROWS 5
const char* labels[MAX_ITEMS] = {
"NRF1",
"NRF2",
"LINK",
"CC1101",
"BUTTONS",
"OLED"
};
bool values[MAX_ITEMS];
int selectedIndex = 0;
int offset = 0;
void drawStatus(DeviceStatus &s)
{
values[0] = s.nrf1;
values[1] = s.nrf2;
values[2] = s.nrf_link;
values[3] = s.cc1101;
values[4] = s.buttons;
values[5] = s.oled;
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tr);
// scrolling logic
if (selectedIndex < offset)
offset = selectedIndex;
if (selectedIndex >= offset + VISIBLE_ROWS)
offset = selectedIndex - VISIBLE_ROWS + 1;
for (int i = 0; i < VISIBLE_ROWS; i++)
{
int item = offset + i;
if (item >= MAX_ITEMS) break;
int y = 12 + i * 10;
if (item == selectedIndex)
{
u8g2.drawBox(0, y - 9, 128, 10);
u8g2.setDrawColor(0);
}
u8g2.drawStr(2, y, labels[item]);
if (values[item])
u8g2.drawStr(80, y, "OK");
else
u8g2.drawStr(80, y, "FAIL");
if (item == selectedIndex)
u8g2.setDrawColor(1);
}
u8g2.sendBuffer();
}
bool testNRFLink()
{
const byte address[6] = "00001";
uint8_t payload = 0xAB;
uint8_t received = 0;
// --- init radios ---
if (!radio1.begin(RADIO_SPI)) return false;
if (!radio2.begin(RADIO_SPI)) return false;
radio1.setPALevel(RF24_PA_LOW);
radio2.setPALevel(RF24_PA_LOW);
radio1.setDataRate(RF24_1MBPS);
radio2.setDataRate(RF24_1MBPS);
radio1.setChannel(100);
radio2.setChannel(100);
radio1.setAutoAck(false);
radio2.setAutoAck(false);
// --- configure pipes ---
radio1.openWritingPipe(address);
radio2.openReadingPipe(0, address);
radio2.startListening();
delay(50);
// --- send ---
radio1.stopListening();
bool sent = radio1.write(&payload, sizeof(payload));
if (!sent) return false;
// --- receive ---
unsigned long start = millis();
while (millis() - start < 200)
{
if (radio2.available())
{
radio2.read(&received, sizeof(received));
return (received == payload);
}
}
return false;
}
// ===== MAIN =====
void device_check_run()
{
DeviceStatus status;
Serial.println("Running device diagnostics...");
// NRF
// NRF link test
status.nrf_link = testNRFLink();
status.nrf1 = checkNRF(radio1);
status.nrf2 = checkNRF(radio2);
// CC1101
status.cc1101 = checkCC1101();
// Buttons
status.buttons = checkButtons();
drawStatus(status);
Serial.println("Diagnostics complete");
while (1)
{
drawStatus(status);
if (btnUp())
{
selectedIndex--;
if (selectedIndex < 0) selectedIndex = MAX_ITEMS - 1;
delay(150);
}
if (btnDown())
{
selectedIndex++;
if (selectedIndex >= MAX_ITEMS) selectedIndex = 0;
delay(150);
}
if (btnBack())
{
delay(150);
break;
}
}}

3
firmware/device_check.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void device_check_run();

16
firmware/display.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "display.h"
#include <Wire.h>
#include "config.h"
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(
U8G2_R0,
U8X8_PIN_NONE
);
void displayInit()
{
Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN);
u8g2.begin();
u8g2.setFont(u8g2_font_6x12_tr);
}

7
firmware/display.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <U8g2lib.h>
extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2;
void displayInit();

128
firmware/firmware.ino Normal file
View File

@ -0,0 +1,128 @@
#include <Arduino.h>
#include <USB.h>
#include <USBHIDKeyboard.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <RF24.h>
#include <nRF24L01.h>
#include "ELECHOUSE_CC1101_SRC_DRV.h"
#include <WiFi.h>
#include <esp_wifi.h>
#include <esp_chip_info.h>
#include <esp_heap_caps.h>
#include <esp_system.h>
#include <SPI.h>
#include "display.h"
#include "buttons.h"
#include "menu.h"
#include "config.h"
#include "cc1101.h"
// ================= USB HID =================
USBHIDKeyboard Keyboard;
RF24 radio1(CE1_PIN, CSN1_PIN);
RF24 radio2(CE2_PIN, CSN2_PIN);
SPIClass *RADIO_SPI;
// ================= BLE SCAN =================
BLEScan *pBLEScan;
void startBLEScan()
{
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setActiveScan(true);
pBLEScan->start(5);
Serial.println("BLE scan complete");
}
// ================= SYSTEM INFO =================
void printSystemUsage()
{
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
Serial.printf("CPU cores: %d\n", chip_info.cores);
Serial.printf(
"Free heap: %d bytes\n",
heap_caps_get_free_size(MALLOC_CAP_DEFAULT)
);
Serial.printf(
"PSRAM free: %d bytes\n",
heap_caps_get_free_size(MALLOC_CAP_SPIRAM)
);
}
void showSplash()
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_logisoso20_tr); // big font
u8g2.drawStr(10, 40, "Orion-RF");
u8g2.setFont(u8g2_font_5x8_tr); // small subtitle
u8g2.drawStr(25, 58, "Initializing...");
u8g2.sendBuffer();
delay(1500); // 1.5 sec
}
// ================= SETUP =================
void setup()
{
Serial.begin(115200);
displayInit();
showSplash();
buttonsInit();
menuInit();
delay(1500);
USB.begin();
Keyboard.begin();
// NRF SPI safety
pinMode(CSN1_PIN, OUTPUT);
digitalWrite(CSN1_PIN, HIGH);
pinMode(CSN2_PIN, OUTPUT);
digitalWrite(CSN2_PIN, HIGH);
RADIO_SPI = new SPIClass(FSPI);
RADIO_SPI->begin(NRF_SCK, NRF_MISO, NRF_MOSI);
printSystemUsage();
Serial.println("SYSTEM READY");
}
// ================= LOOP =================
void loop()
{
menuLoop();
}

278
firmware/menu.cpp Normal file
View File

@ -0,0 +1,278 @@
#include <Arduino.h>
#include "menu.h"
#include "display.h"
#include "buttons.h"
#include "badusb.h"
#include "nrf24.h"
#include "cc1101.h"
#include "blescanner.h"
#include "wifi_scan.h"
#include "wifi_analyzer.h"
#include "device_check.h"
// ================= FEATURE HANDLERS =================
void runSystemInfoFeature();
void runRFCaptureFeature();
void runBLEScanFeature();
// ================= MENU DATA =================
// Root menu
const char *mainMenuItems[] = {
"BadUSB",
"RF Capture",
"NRF Jammer",
"BLE Scan",
"Wifi Scan",
"Wifi Analyzer",
"System Info",
"Device Check",
"Restart"
};
Menu mainMenu = {mainMenuItems, sizeof(mainMenuItems) / sizeof(mainMenuItems[0])};
// BadUSB submenu
const char *badusbItems[] = {
"Demo",
"Open CMD",
"Rickroll"};
Menu badusbMenu = {badusbItems, 3};
// ================= MENU STATE =================
Menu *currentMenu = &mainMenu;
int menuIndex = 0;
int menuOffset = 0;
#define MENU_VISIBLE_ROWS 4
bool insideFeature = false;
// ================= DRAW =================
void drawMenu()
{
u8g2.clearBuffer();
// scroll handling
if (menuIndex < menuOffset)
menuOffset = menuIndex;
if (menuIndex >= menuOffset + MENU_VISIBLE_ROWS)
menuOffset = menuIndex - MENU_VISIBLE_ROWS + 1;
for (int i = 0; i < MENU_VISIBLE_ROWS; i++)
{
int item = menuOffset + i;
if (item >= currentMenu->size)
break;
if (item == menuIndex)
u8g2.drawStr(0, 14 + i * 14, ">");
u8g2.drawStr(10, 14 + i * 14, currentMenu->items[item]);
}
// scroll indicators
if (menuOffset > 0)
u8g2.drawStr(118, 10, "^");
if (menuOffset + MENU_VISIBLE_ROWS < currentMenu->size)
u8g2.drawStr(118, 62, "v");
u8g2.sendBuffer();
}
// ================= FEATURE EXECUTION =================
void launchFeature()
{
insideFeature = true;
if (currentMenu == &mainMenu)
{
switch (menuIndex)
{
case 0: // BadUSB → enter submenu
currentMenu = &badusbMenu;
menuIndex = 0;
menuOffset = 0;
break;
case 1:
if (!isCC1101Ready()) {
if (!initCC1101()) {
Serial.println("CC1101 failed");
return;
}
}
Serial.println("Ready to capture...");
startCapture();
delay(5000);
stopCapture();
printCapture();
break;
case 2:
startNRFJammer();
break;
case 3:
ble_scan();
ble_drawMenu();
while (1) {
ble_loop();
if (btnBack())
break;
}
break;
case 4:
{
// Start scan once
wifi_scan_start();
wifi_scan_draw();
while (1) {
wifi_scan_loop();
// EXIT condition handled ONLY here
if (btnBack()) {
delay(150); // debounce
break;
}
}
break;
}
case 5:
{
wifi_analyzer_start();
bool prevBack = false;
while (1)
{
wifi_analyzer_loop();
bool nowBack = btnBack();
if (nowBack && !prevBack)
{
delay(150);
break;
}
prevBack = nowBack;
}
break;
}
case 6:
runSystemInfoFeature();
break;
case 7:
device_check_run();
break;
case 8:
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x13_tr);
u8g2.drawStr(30, 30, "Restarting...");
u8g2.sendBuffer();
delay(1000);
ESP.restart();
break;
}
}
else if (currentMenu == &badusbMenu)
{
switch (menuIndex)
{
case 0:
runBadUSBDemo();
break;
case 1:
Serial.println("Open CMD payload");
runBadUSBOpenCMD();
break;
case 2:
Serial.println("Rickroll payload");
runBadUSBRickroll();
break;
}
}
insideFeature = false;
drawMenu();
}
// ================= INIT =================
void menuInit()
{
currentMenu = &mainMenu;
menuIndex = 0;
menuOffset = 0;
drawMenu();
}
// ================= LOOP =================
void menuLoop()
{
static uint32_t lastPress = 0;
if (insideFeature)
return;
if (millis() - lastPress < 150)
return;
if (btnUp())
{
menuIndex--;
if (menuIndex < 0)
menuIndex = currentMenu->size - 1;
drawMenu();
lastPress = millis();
}
else if (btnDown())
{
menuIndex++;
if (menuIndex >= currentMenu->size)
menuIndex = 0;
drawMenu();
lastPress = millis();
}
else if (btnSelect())
{
launchFeature();
lastPress = millis();
}
else if (btnBack())
{
if (currentMenu != &mainMenu)
{
currentMenu = &mainMenu;
menuIndex = 0;
menuOffset = 0;
drawMenu();
}
lastPress = millis();
}
}

10
firmware/menu.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
struct Menu
{
const char **items;
int size;
};
void menuInit();
void menuLoop();

99
firmware/nrf24.cpp Normal file
View File

@ -0,0 +1,99 @@
#include <Arduino.h>
#include <RF24.h>
#include "buttons.h"
#include "nrf24.h"
#include "display.h"
#define JAM_DURATION 500
extern SPIClass *RADIO_SPI;
extern RF24 radio1;
extern RF24 radio2;
void initNRF(RF24 &radio)
{
radio.begin(RADIO_SPI);
radio.setAutoAck(false);
radio.stopListening();
radio.setRetries(0, 0);
radio.setDataRate(RF24_2MBPS);
radio.setPALevel(RF24_PA_MAX);
radio.openWritingPipe(0xE7E7E7E7E7LL);
}
void jamChannels(const char* label, int startCh, int endCh) {
byte data1[32], data2[32];
for (int i = 0; i < 32; i++) {
data1[i] = random(0, 256);
data2[i] = random(0, 256);
}
for (int ch = startCh; ch <= endCh; ch++) {
// Status screen
u8g2.clearBuffer();
u8g2.drawStr(0, 10, "Jamming:");
u8g2.setCursor(60, 10);
u8g2.print(label);
u8g2.setCursor(0, 30);
u8g2.print("Channel: ");
u8g2.print(ch);
u8g2.sendBuffer();
unsigned long startTime = millis();
while (millis() - startTime < JAM_DURATION) {
radio1.setChannel(ch);
radio1.stopListening();
radio1.write(data1, sizeof(data1));
delayMicroseconds(100);
radio2.setChannel(ch);
radio2.stopListening();
radio2.write(data2, sizeof(data2));
delayMicroseconds(100);
}
}
}
void nrfJammerSweep()
{
static uint8_t ch1 = 0;
static uint8_t ch2 = 124;
uint8_t payload[32] = {0xFF};
radio1.setChannel(ch1);
radio1.writeFast(payload, sizeof(payload));
radio2.setChannel(ch2);
radio2.writeFast(payload, sizeof(payload));
ch1++;
ch2--;
if (ch1 > 124) ch1 = 0;
if (ch2 > 124) ch2 = 124;
}
void startNRFJammer()
{
initNRF(radio1);
initNRF(radio2);
Serial.println("NRF JAMMER STARTED");
// nrfJammerSweep();
jamChannels("Bluetooth", 0, 78);
if (btnBack())
{
Serial.println("Jammer stopped");
return;
}
delayMicroseconds(200);
}

14
firmware/nrf24.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <RF24.h>
// Initialization
void initNRF(RF24 &radio);
// Jammer modes
void startNRFJammer(); // dual-radio sweep jammer
void stopNRFJammer(); // (optional, for future)
// Advanced (later)
void nrfJammerSweep(); // internal, but can expose if needed
void nrfSetChannel(uint8_t ch);

13
firmware/stubs.cpp Normal file
View File

@ -0,0 +1,13 @@
#include <Arduino.h>
void runRFCaptureFeature()
{
Serial.println("RF Capture not implemented yet");
}
void runBLEScanFeature()
{
Serial.println("BLE Scan not implemented yet");
}

87
firmware/sysinfo.cpp Normal file
View File

@ -0,0 +1,87 @@
#include <Arduino.h>
#include "display.h"
#include "buttons.h"
#include <esp_chip_info.h>
#include <esp_heap_caps.h>
void runSystemInfoFeature()
{
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
while (true)
{
//u8g2.clearBuffer();
//char buf[32];
//sprintf(buf, "Cores: %d", chip_info.cores);
//u8g2.drawStr(0, 14, buf);
//sprintf(buf, "Heap: %d",
// heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
//u8g2.drawStr(0, 28, buf);
//u8g2.drawStr(0, 60, "BACK to exit");
// Get RAM info
size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
size_t totalHeap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
int ramUsage = 100 - ((freeHeap * 100) / totalHeap);
// Get Flash info
//uint32_t flashSize = spi_flash_get_chip_size();
uint32_t flashSize = ESP.getFlashChipSize();
uint32_t flashUsed = ESP.getSketchSize();
int flashUsage = (flashUsed * 100) / flashSize;
// Temperature (approx)
uint8_t temperature = temperatureRead();
// Chip info
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x12_tr);
char buf[32];
// Box 1 - RAM
u8g2.drawFrame(0, 0, 128, 12);
sprintf(buf, "RAM: %d%% used", ramUsage);
u8g2.drawStr(4, 9, buf);
// Box 2 - Flash
u8g2.drawFrame(0, 12, 128, 12);
sprintf(buf, "Flash: %d%% used", flashUsage);
u8g2.drawStr(4, 21, buf);
// Box 3 - Temp (FULL WIDTH now)
u8g2.drawFrame(0, 24, 128, 12);
sprintf(buf, "Temp: %d C", temperature);
u8g2.drawStr(4, 33, buf);
// Box 4 - Chip info (FULL WIDTH)
u8g2.drawFrame(0, 36, 128, 12);
sprintf(buf, "Cores: %d Rev: %d", chip_info.cores, chip_info.revision);
u8g2.drawStr(4, 45, buf);
// Box 5 - PSRAM (KB)
u8g2.drawFrame(0, 48, 128, 12);
sprintf(buf, "PSRAM: %lu KB", heap_caps_get_free_size(MALLOC_CAP_SPIRAM) / 1024);
u8g2.drawStr(4, 57, buf);
u8g2.sendBuffer();
if (btnBack())
{
delay(200);
return;
}
delay(100);
}
}

3
firmware/sysinfo.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void runSystemInfoFeature();

147
firmware/wifi_analyzer.cpp Normal file
View File

@ -0,0 +1,147 @@
#include <Arduino.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include "display.h"
#include "buttons.h"
// ===== CONFIG =====
#define GRAPH_WIDTH 128
#define GRAPH_HEIGHT 44
#define GRAPH_TOP 10
#define MAX_POINTS 128
#define SPIKE_THRESHOLD 30
// ===== STATE =====
struct SnifferGraph {
uint8_t graphData[MAX_POINTS];
uint8_t currentChannel = 1;
volatile uint16_t packetCounter = 0;
unsigned long lastChannelSwitch = 0;
unsigned long lastUpdate = 0;
};
static SnifferGraph sniffer;
// ===== CALLBACK =====
void IRAM_ATTR snifferCallback(void *buf, wifi_promiscuous_pkt_type_t type)
{
if (type == WIFI_PKT_MGMT || type == WIFI_PKT_DATA || type == WIFI_PKT_CTRL)
{
sniffer.packetCounter++;
}
}
// ===== INIT =====
void wifi_analyzer_start()
{
// display init (safe to call again)
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tr);
u8g2.drawStr(0, 10, "Starting analyzer...");
u8g2.sendBuffer();
// reset graph
memset(sniffer.graphData, 0, sizeof(sniffer.graphData));
sniffer.packetCounter = 0;
sniffer.currentChannel = 1;
// reset WiFi
WiFi.disconnect(true, true);
esp_wifi_stop();
delay(200);
esp_wifi_deinit();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_wifi_set_storage(WIFI_STORAGE_RAM);
esp_wifi_set_mode(WIFI_MODE_NULL);
esp_wifi_start();
esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous_rx_cb(snifferCallback);
esp_wifi_set_promiscuous(true);
}
// ===== HELPERS =====
static void switchChannel()
{
sniffer.currentChannel++;
if (sniffer.currentChannel > 13) sniffer.currentChannel = 1;
esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
}
static void updateGraph(uint8_t value)
{
for (int i = 0; i < MAX_POINTS - 1; i++)
{
sniffer.graphData[i] = sniffer.graphData[i + 1];
}
sniffer.graphData[MAX_POINTS - 1] = value;
}
static void drawGraph(uint16_t pktCount)
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tr);
char line1[16];
char line2[16];
sprintf(line1, "Ch:%d", sniffer.currentChannel);
sprintf(line2, "Pkts:%d", pktCount * 5);
u8g2.drawStr(0, 8, line1);
u8g2.drawStr(60, 8, line2);
for (int x = 1; x < GRAPH_WIDTH; x++)
{
int y1 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x - 1];
int y2 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x];
u8g2.drawLine(x - 1, y1, x, y2);
}
if (pktCount >= SPIKE_THRESHOLD)
{
u8g2.drawVLine(GRAPH_WIDTH / 2, GRAPH_TOP, GRAPH_HEIGHT);
}
u8g2.sendBuffer();
}
// ===== LOOP =====
void wifi_analyzer_loop()
{
static uint32_t lastPress = 0;
unsigned long now = millis();
// channel hopping
if (now - sniffer.lastChannelSwitch >= 1000)
{
sniffer.lastChannelSwitch = now;
switchChannel();
}
// graph update
if (now - sniffer.lastUpdate >= 200)
{
sniffer.lastUpdate = now;
uint16_t pktCount = sniffer.packetCounter;
uint8_t scaled = pktCount * 2;
uint8_t value = min(scaled, (uint8_t)GRAPH_HEIGHT);
updateGraph(value);
drawGraph(pktCount);
sniffer.packetCounter = 0;
}
// optional: small debounce to not hammer CPU
if (millis() - lastPress < 10)
return;
}

4
firmware/wifi_analyzer.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
void wifi_analyzer_start();
void wifi_analyzer_loop();

152
firmware/wifi_scan.cpp Normal file
View File

@ -0,0 +1,152 @@
#include <Arduino.h>
#include <WiFi.h>
#include "display.h"
#include "buttons.h"
#define MAX_NETWORKS 30
struct WiFiNet {
String ssid;
int rssi;
int channel;
bool encrypted;
};
static WiFiNet networks[MAX_NETWORKS];
static int networkCount = 0;
static int selectedIndex = 0;
// ===== SCAN =====
void wifi_scan_start()
{
u8g2.clearBuffer();
u8g2.drawStr(10, 30, "Scanning WiFi...");
u8g2.sendBuffer();
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
int n = WiFi.scanNetworks();
networkCount = min(n, MAX_NETWORKS);
for (int i = 0; i < networkCount; i++)
{
networks[i].ssid = WiFi.SSID(i);
networks[i].rssi = WiFi.RSSI(i);
networks[i].channel = WiFi.channel(i);
networks[i].encrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
}
selectedIndex = 0;
}
// ===== DRAW =====
void wifi_scan_draw()
{
u8g2.clearBuffer();
if (networkCount == 0)
{
u8g2.drawStr(0, 30, "No networks");
u8g2.drawStr(0, 45, "Press BACK");
}
else
{
char counter[20];
sprintf(counter, "%d/%d", selectedIndex + 1, networkCount);
u8g2.setFont(u8g2_font_5x8_tr);
u8g2.drawStr(0, 8, counter);
u8g2.setFont(u8g2_font_6x10_tr);
for (int i = 0; i < 3; i++)
{
int idx = selectedIndex + i;
if (idx >= networkCount) break;
int y = 22 + i * 14;
if (i == 0)
{
u8g2.drawBox(0, y - 10, 128, 12);
u8g2.setDrawColor(0);
}
String text = networks[idx].ssid;
if (text.length() > 10)
text = text.substring(0, 10) + "..";
text += " (" + String(networks[idx].rssi) + ")";
u8g2.drawStr(2, y, text.c_str());
if (i == 0)
u8g2.setDrawColor(1);
}
}
u8g2.sendBuffer();
}
// ===== DETAILS =====
void wifi_drawDetails()
{
if (networkCount == 0) return;
WiFiNet &net = networks[selectedIndex];
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_5x8_tr);
u8g2.drawStr(0, 10, net.ssid.c_str());
char rssi[20];
sprintf(rssi, "RSSI: %d", net.rssi);
u8g2.drawStr(0, 20, rssi);
char ch[20];
sprintf(ch, "CH: %d", net.channel);
u8g2.drawStr(0, 30, ch);
u8g2.drawStr(0, 40, net.encrypted ? "Secured" : "Open");
u8g2.sendBuffer();
}
// ===== LOOP =====
void wifi_scan_loop()
{
static uint32_t lastPress = 0;
if (millis() - lastPress < 150)
return;
if (btnDown() && selectedIndex < networkCount - 1)
{
selectedIndex++;
wifi_scan_draw();
lastPress = millis();
}
else if (btnUp() && selectedIndex > 0)
{
selectedIndex--;
wifi_scan_draw();
lastPress = millis();
}
else if (btnSelect() && networkCount > 0)
{
wifi_drawDetails();
delay(3000);
wifi_scan_draw();
lastPress = millis();
}
// else if (btnBack())
// {
// wifi_scan_start();
// wifi_scan_draw();
// lastPress = millis();
// }
}

5
firmware/wifi_scan.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void wifi_scan_start();
void wifi_scan_loop();
void wifi_scan_draw();