mirror of
https://github.com/Freenove/Freenove_ESP32_WROVER_Board.git
synced 2025-07-28 15:47:15 +00:00
upload
This commit is contained in:
parent
3e121a15db
commit
af25131b0f
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
docs/build
|
||||
*.mo
|
13
.readthedocs.yaml
Normal file
13
.readthedocs.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
version: "2"
|
||||
|
||||
build:
|
||||
os: "ubuntu-22.04"
|
||||
tools:
|
||||
python: "3.10"
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
BIN
About_Fakes.pdf
BIN
About_Fakes.pdf
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
BIN
C/C_Tutorial.pdf
BIN
C/C_Tutorial.pdf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
/**********************************************************************
|
||||
* Filename : Blink
|
||||
* Description : Make an led blinking.
|
||||
* Auther : www.freenove.com
|
||||
* Modification: 2024/06/18
|
||||
**********************************************************************/
|
||||
#define LED_BUILTIN 2
|
||||
// the setup function runs once when you press reset or power the board
|
||||
void setup() {
|
||||
// initialize digital pin LED_BUILTIN as an output.
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
}
|
||||
|
||||
// the loop function runs over and over again forever
|
||||
void loop() {
|
||||
digitalWrite(LED_BUILTIN, HIGH); // turn the LED off (HIGH is the voltage level)
|
||||
delay(1000); // wait for a second
|
||||
digitalWrite(LED_BUILTIN, LOW); // turn the LED on by making the voltage LOW
|
||||
delay(1000); // wait for a second
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : SerialToSerialBT
|
||||
Description : ESP32 communicates with the phone by bluetooth and print phone's data via a serial port
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/19
|
||||
**********************************************************************/
|
||||
#include "BluetoothSerial.h"
|
||||
|
||||
BluetoothSerial SerialBT;
|
||||
String buffer;
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
SerialBT.begin("ESP32test"); //Bluetooth device name
|
||||
Serial.println("\nThe device started, now you can pair it with bluetooth!");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (Serial.available()) {
|
||||
SerialBT.write(Serial.read());
|
||||
}
|
||||
if (SerialBT.available()) {
|
||||
Serial.write(SerialBT.read());
|
||||
}
|
||||
delay(20);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : BLE_USART
|
||||
Description : Esp32 communicates with the phone by BLE and sends incoming data via a serial port
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/19
|
||||
**********************************************************************/
|
||||
#include "BLEDevice.h"
|
||||
#include "BLEServer.h"
|
||||
#include "BLEUtils.h"
|
||||
#include "BLE2902.h"
|
||||
|
||||
BLECharacteristic *pCharacteristic;
|
||||
bool deviceConnected = false;
|
||||
uint8_t txValue = 0;
|
||||
long lastMsg = 0;
|
||||
String rxload="Test\n";
|
||||
|
||||
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
|
||||
class MyServerCallbacks: public BLEServerCallbacks {
|
||||
void onConnect(BLEServer* pServer) {
|
||||
deviceConnected = true;
|
||||
};
|
||||
void onDisconnect(BLEServer* pServer) {
|
||||
deviceConnected = false;
|
||||
//pServer->getAdvertising()->start(); //Reopen the pServer and wait for the connection.
|
||||
}
|
||||
};
|
||||
|
||||
class MyCallbacks: public BLECharacteristicCallbacks {
|
||||
void onWrite(BLECharacteristic *pCharacteristic) {
|
||||
String rxValue = pCharacteristic->getValue();
|
||||
if (rxValue.length() > 0) {
|
||||
rxload="";
|
||||
for (int i = 0; i < rxValue.length(); i++){
|
||||
rxload +=(char)rxValue[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void setupBLE(String BLEName){
|
||||
const char *ble_name=BLEName.c_str();
|
||||
BLEDevice::init(ble_name);
|
||||
BLEServer *pServer = BLEDevice::createServer();
|
||||
pServer->setCallbacks(new MyServerCallbacks());
|
||||
BLEService *pService = pServer->createService(SERVICE_UUID);
|
||||
pCharacteristic= pService->createCharacteristic(CHARACTERISTIC_UUID_TX,BLECharacteristic::PROPERTY_NOTIFY);
|
||||
pCharacteristic->addDescriptor(new BLE2902());
|
||||
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX,BLECharacteristic::PROPERTY_WRITE);
|
||||
pCharacteristic->setCallbacks(new MyCallbacks());
|
||||
pService->start();
|
||||
pServer->getAdvertising()->start();
|
||||
Serial.println("Waiting a client connection to notify...");
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
setupBLE("ESP32_Bluetooth");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
long now = millis();
|
||||
if (now - lastMsg > 100) {
|
||||
if (deviceConnected&&rxload.length()>0) {
|
||||
Serial.println(rxload);
|
||||
rxload="";
|
||||
}
|
||||
if(Serial.available()>0){
|
||||
String str=Serial.readString();
|
||||
const char *newValue=str.c_str();
|
||||
pCharacteristic->setValue(newValue);
|
||||
pCharacteristic->notify();
|
||||
}
|
||||
lastMsg = now;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : SDMMC Test
|
||||
Description : The SD card is accessed using the SDMMC one-bit bus
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include "sd_read_write.h"
|
||||
#include "SD_MMC.h"
|
||||
|
||||
#define SD_MMC_CMD 15 //Please do not modify it.
|
||||
#define SD_MMC_CLK 14 //Please do not modify it.
|
||||
#define SD_MMC_D0 2 //Please do not modify it.
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
|
||||
if (!SD_MMC.begin("/sdcard", true, true, SDMMC_FREQ_DEFAULT, 5)) {
|
||||
Serial.println("Card Mount Failed");
|
||||
return;
|
||||
}
|
||||
uint8_t cardType = SD_MMC.cardType();
|
||||
if(cardType == CARD_NONE){
|
||||
Serial.println("No SD_MMC card attached");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("SD_MMC Card Type: ");
|
||||
if(cardType == CARD_MMC){
|
||||
Serial.println("MMC");
|
||||
} else if(cardType == CARD_SD){
|
||||
Serial.println("SDSC");
|
||||
} else if(cardType == CARD_SDHC){
|
||||
Serial.println("SDHC");
|
||||
} else {
|
||||
Serial.println("UNKNOWN");
|
||||
}
|
||||
|
||||
uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
|
||||
Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize);
|
||||
|
||||
listDir(SD_MMC, "/", 0);
|
||||
|
||||
createDir(SD_MMC, "/mydir");
|
||||
listDir(SD_MMC, "/", 0);
|
||||
|
||||
removeDir(SD_MMC, "/mydir");
|
||||
listDir(SD_MMC, "/", 2);
|
||||
|
||||
writeFile(SD_MMC, "/hello.txt", "Hello ");
|
||||
appendFile(SD_MMC, "/hello.txt", "World!\n");
|
||||
readFile(SD_MMC, "/hello.txt");
|
||||
|
||||
deleteFile(SD_MMC, "/foo.txt");
|
||||
renameFile(SD_MMC, "/hello.txt", "/foo.txt");
|
||||
readFile(SD_MMC, "/foo.txt");
|
||||
|
||||
testFileIO(SD_MMC, "/test.txt");
|
||||
|
||||
Serial.printf("Total space: %lluMB\r\n", SD_MMC.totalBytes() / (1024 * 1024));
|
||||
Serial.printf("Used space: %lluMB\r\n", SD_MMC.usedBytes() / (1024 * 1024));
|
||||
}
|
||||
|
||||
void loop(){
|
||||
delay(10000);
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
#include "sd_read_write.h"
|
||||
|
||||
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
|
||||
Serial.printf("Listing directory: %s\n", dirname);
|
||||
|
||||
File root = fs.open(dirname);
|
||||
if(!root){
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
if(!root.isDirectory()){
|
||||
Serial.println("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
File file = root.openNextFile();
|
||||
while(file){
|
||||
if(file.isDirectory()){
|
||||
Serial.print(" DIR : ");
|
||||
Serial.println(file.name());
|
||||
if(levels){
|
||||
listDir(fs, file.path(), levels -1);
|
||||
}
|
||||
} else {
|
||||
Serial.print(" FILE: ");
|
||||
Serial.print(file.name());
|
||||
Serial.print(" SIZE: ");
|
||||
Serial.println(file.size());
|
||||
}
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
|
||||
void createDir(fs::FS &fs, const char * path){
|
||||
Serial.printf("Creating Dir: %s\n", path);
|
||||
if(fs.mkdir(path)){
|
||||
Serial.println("Dir created");
|
||||
} else {
|
||||
Serial.println("mkdir failed");
|
||||
}
|
||||
}
|
||||
|
||||
void removeDir(fs::FS &fs, const char * path){
|
||||
Serial.printf("Removing Dir: %s\n", path);
|
||||
if(fs.rmdir(path)){
|
||||
Serial.println("Dir removed");
|
||||
} else {
|
||||
Serial.println("rmdir failed");
|
||||
}
|
||||
}
|
||||
|
||||
void readFile(fs::FS &fs, const char * path){
|
||||
Serial.printf("Reading file: %s\n", path);
|
||||
|
||||
File file = fs.open(path);
|
||||
if(!file){
|
||||
Serial.println("Failed to open file for reading");
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.print("Read from file: ");
|
||||
while(file.available()){
|
||||
Serial.write(file.read());
|
||||
}
|
||||
}
|
||||
|
||||
void writeFile(fs::FS &fs, const char * path, const char * message){
|
||||
Serial.printf("Writing file: %s\n", path);
|
||||
|
||||
File file = fs.open(path, FILE_WRITE);
|
||||
if(!file){
|
||||
Serial.println("Failed to open file for writing");
|
||||
return;
|
||||
}
|
||||
if(file.print(message)){
|
||||
Serial.println("File written");
|
||||
} else {
|
||||
Serial.println("Write failed");
|
||||
}
|
||||
}
|
||||
|
||||
void appendFile(fs::FS &fs, const char * path, const char * message){
|
||||
Serial.printf("Appending to file: %s\n", path);
|
||||
|
||||
File file = fs.open(path, FILE_APPEND);
|
||||
if(!file){
|
||||
Serial.println("Failed to open file for appending");
|
||||
return;
|
||||
}
|
||||
if(file.print(message)){
|
||||
Serial.println("Message appended");
|
||||
} else {
|
||||
Serial.println("Append failed");
|
||||
}
|
||||
}
|
||||
|
||||
void renameFile(fs::FS &fs, const char * path1, const char * path2){
|
||||
Serial.printf("Renaming file %s to %s\n", path1, path2);
|
||||
if (fs.rename(path1, path2)) {
|
||||
Serial.println("File renamed");
|
||||
} else {
|
||||
Serial.println("Rename failed");
|
||||
}
|
||||
}
|
||||
|
||||
void deleteFile(fs::FS &fs, const char * path){
|
||||
Serial.printf("Deleting file: %s\n", path);
|
||||
if(fs.remove(path)){
|
||||
Serial.println("File deleted");
|
||||
} else {
|
||||
Serial.println("Delete failed");
|
||||
}
|
||||
}
|
||||
|
||||
void testFileIO(fs::FS &fs, const char * path){
|
||||
File file = fs.open(path);
|
||||
static uint8_t buf[512];
|
||||
size_t len = 0;
|
||||
uint32_t start = millis();
|
||||
uint32_t end = start;
|
||||
if(file){
|
||||
len = file.size();
|
||||
size_t flen = len;
|
||||
start = millis();
|
||||
while(len){
|
||||
size_t toRead = len;
|
||||
if(toRead > 512){
|
||||
toRead = 512;
|
||||
}
|
||||
file.read(buf, toRead);
|
||||
len -= toRead;
|
||||
}
|
||||
end = millis() - start;
|
||||
Serial.printf("%u bytes read for %u ms\r\n", flen, end);
|
||||
file.close();
|
||||
} else {
|
||||
Serial.println("Failed to open file for reading");
|
||||
}
|
||||
|
||||
file = fs.open(path, FILE_WRITE);
|
||||
if(!file){
|
||||
Serial.println("Failed to open file for writing");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
start = millis();
|
||||
for(i=0; i<2048; i++){
|
||||
file.write(buf, 512);
|
||||
}
|
||||
end = millis() - start;
|
||||
Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
|
||||
file.close();
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#ifndef __SD_READ_WRITE_H
|
||||
#define __SD_READ_WRITE_H
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "FS.h"
|
||||
|
||||
|
||||
void listDir(fs::FS &fs, const char * dirname, uint8_t levels);
|
||||
void createDir(fs::FS &fs, const char * path);
|
||||
void removeDir(fs::FS &fs, const char * path);
|
||||
void readFile(fs::FS &fs, const char * path);
|
||||
void writeFile(fs::FS &fs, const char * path, const char * message);
|
||||
void appendFile(fs::FS &fs, const char * path, const char * message);
|
||||
void renameFile(fs::FS &fs, const char * path1, const char * path2);
|
||||
void deleteFile(fs::FS &fs, const char * path);
|
||||
void testFileIO(fs::FS &fs, const char * path);
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : WiFi Station
|
||||
Description : Connect to your router using ESP32
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include <WiFi.h>
|
||||
|
||||
const char *ssid_Router = "********"; //Enter the router name
|
||||
const char *password_Router = "********"; //Enter the router password
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
delay(2000);
|
||||
Serial.println("Setup start");
|
||||
WiFi.begin(ssid_Router, password_Router);
|
||||
Serial.println(String("Connecting to ")+ssid_Router);
|
||||
while (WiFi.status() != WL_CONNECTED){
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("\nConnected, IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.println("Setup End");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : WiFi AP
|
||||
Description : Set ESP32 to open an access point
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include <WiFi.h>
|
||||
|
||||
const char *ssid_AP = "WiFi_Name"; //Enter the router name
|
||||
const char *password_AP = "12345678"; //Enter the router password
|
||||
|
||||
IPAddress local_IP(192,168,1,100);//Set the IP address of ESP32 itself
|
||||
IPAddress gateway(192,168,1,10); //Set the gateway of ESP32 itself
|
||||
IPAddress subnet(255,255,255,0); //Set the subnet mask for ESP32 itself
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
delay(2000);
|
||||
Serial.println("Setting soft-AP configuration ... ");
|
||||
WiFi.disconnect();
|
||||
WiFi.mode(WIFI_AP);
|
||||
Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
|
||||
Serial.println("Setting soft-AP ... ");
|
||||
boolean result = WiFi.softAP(ssid_AP, password_AP);
|
||||
if(result){
|
||||
Serial.println("Ready");
|
||||
Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP().toString());
|
||||
Serial.println(String("MAC address = ") + WiFi.softAPmacAddress().c_str());
|
||||
}else{
|
||||
Serial.println("Failed!");
|
||||
}
|
||||
Serial.println("Setup End");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : WiFi AP+Station
|
||||
Description : ESP32 connects to the user's router, turning on an access point
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include <WiFi.h>
|
||||
|
||||
const char *ssid_Router = "********"; //Enter the router name
|
||||
const char *password_Router = "********"; //Enter the router password
|
||||
const char *ssid_AP = "WiFi_Name"; //Enter the router name
|
||||
const char *password_AP = "12345678"; //Enter the router password
|
||||
|
||||
void setup(){
|
||||
Serial.begin(115200);
|
||||
Serial.println("Setting soft-AP configuration ... ");
|
||||
WiFi.disconnect();
|
||||
WiFi.mode(WIFI_AP);
|
||||
Serial.println("Setting soft-AP ... ");
|
||||
boolean result = WiFi.softAP(ssid_AP, password_AP);
|
||||
if(result){
|
||||
Serial.println("Ready");
|
||||
Serial.println(String("Soft-AP IP address = ") + WiFi.softAPIP().toString());
|
||||
Serial.println(String("MAC address = ") + WiFi.softAPmacAddress().c_str());
|
||||
}else{
|
||||
Serial.println("Failed!");
|
||||
}
|
||||
|
||||
Serial.println("\nSetting Station configuration ... ");
|
||||
WiFi.begin(ssid_Router, password_Router);
|
||||
Serial.println(String("Connecting to ")+ ssid_Router);
|
||||
while (WiFi.status() != WL_CONNECTED){
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("\nConnected, IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.println("Setup End");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : WiFi Client
|
||||
Description : Use ESP32's WiFi client feature to connect and communicate with a remote IP.
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include <WiFi.h>
|
||||
|
||||
const char *ssid_Router = "********"; //Enter the router name
|
||||
const char *password_Router = "********"; //Enter the router password
|
||||
#define REMOTE_IP "********" //input the remote server which is you want to connect
|
||||
#define REMOTE_PORT 8888 //input the remote port which is the remote provide
|
||||
WiFiClient client;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(10);
|
||||
|
||||
WiFi.begin(ssid_Router, password_Router);
|
||||
Serial.print("\nWaiting for WiFi... ");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
delay(500);
|
||||
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(REMOTE_IP);
|
||||
|
||||
while (!client.connect(REMOTE_IP, REMOTE_PORT)) {
|
||||
Serial.println("Connection failed.");
|
||||
Serial.println("Waiting a moment before retrying...");
|
||||
}
|
||||
Serial.println("Connected");
|
||||
client.print("Hello\n");
|
||||
client.print("This is my IP.\n");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (client.available() > 0) {
|
||||
delay(20);
|
||||
//read back one line from the server
|
||||
String line = client.readString();
|
||||
Serial.println(REMOTE_IP + String(":") + line);
|
||||
}
|
||||
if (Serial.available() > 0) {
|
||||
delay(20);
|
||||
String line = Serial.readString();
|
||||
client.print(line);
|
||||
}
|
||||
if (client.connected () == 0) {
|
||||
client.stop();
|
||||
WiFi.disconnect();
|
||||
}
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch WiFi Client and Server
|
||||
* Author Zhentao Lin @ Freenove (http://www.freenove.com)
|
||||
* Date 2020/7/11
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to control a 2D ellipse through communicate to an
|
||||
* ESP32 board or other micro controller.
|
||||
* It will automatically detect and connect to a device (serial port) which
|
||||
* use the same trans format.
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import controlP5.*;
|
||||
import processing.net.*;
|
||||
|
||||
ControlP5 cp5;
|
||||
//Println console;
|
||||
Server myServer;
|
||||
Client myClient;
|
||||
int dataIn=0;
|
||||
int radioFlag1=0;
|
||||
int radioFlag2=0;
|
||||
int send_flag=1;
|
||||
|
||||
void setup() {
|
||||
size(600,400);
|
||||
smooth();
|
||||
noStroke();
|
||||
cp5 = new ControlP5(this);
|
||||
cp5.addTab("default")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setLabel("TCP Server")
|
||||
.setId(1)
|
||||
;
|
||||
cp5.getTab("TCP Client")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setId(2)
|
||||
;
|
||||
|
||||
cp5.addTextfield("Local IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addTextfield("Local PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("8888")
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addRadioButton("connect1")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("Listening", 1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("default")
|
||||
;
|
||||
|
||||
cp5.addTextfield("Remote IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("192.168.1.xxx")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addTextfield("Remote PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("80")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addRadioButton("connect2")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("connect Server",1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
|
||||
cp5.addTextarea("recvData")
|
||||
.setPosition(200,40)
|
||||
.setSize(350,150)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorBackground(color(100,255))
|
||||
.scroll(15)
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addTextfield("sendData")
|
||||
.setPosition(200,230)
|
||||
.setSize(350,80)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setLabel("")
|
||||
.setFocus(true)
|
||||
.setColorBackground(color(100,255))
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearRecv")
|
||||
.setValue(0)
|
||||
.setPosition(200,200)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearSend")
|
||||
.setValue(0)
|
||||
.setPosition(200,320)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("Send")
|
||||
.setValue(0)
|
||||
.setPosition(450,320)
|
||||
.setSize(100,20)
|
||||
.plugTo(this,"send_Textfield_SendData")
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
}
|
||||
|
||||
void draw(){
|
||||
background(220);
|
||||
if(radioFlag1==1){
|
||||
Client thisClient = myServer.available();
|
||||
if (thisClient !=null) {
|
||||
String whatClientSaid = thisClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(thisClient.ip()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// myServer.active()
|
||||
if(radioFlag2==1){
|
||||
if (myClient.available() > 0) {
|
||||
String whatClientSaid = myClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(cp5.get(Textfield.class,"Remote IP").getText()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void controlEvent(ControlEvent theControlEvent) {
|
||||
if (theControlEvent.isTab()) {
|
||||
if(theControlEvent.getTab().getId()==1){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=1;
|
||||
}
|
||||
else if(theControlEvent.getTab().getId()==2){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void connect1(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag1=a;
|
||||
if(radioFlag1==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Local PORT").getText();
|
||||
int port = int(port_buffer);
|
||||
myServer = new Server(this,port);
|
||||
println(Server.ip());
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
println(port);
|
||||
}
|
||||
else
|
||||
myServer.stop();
|
||||
}
|
||||
void connect2(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag2=a;
|
||||
if(radioFlag2==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Remote PORT").getText();
|
||||
String IP_buffer = cp5.get(Textfield.class,"Remote IP").getText();
|
||||
int port = int(port_buffer);
|
||||
if(IP_buffer.compareTo("192.168.1.xxx")==0){
|
||||
println("connect error!");
|
||||
}
|
||||
else{
|
||||
myClient = new Client(this,IP_buffer,port);
|
||||
println("connect success!");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
myClient.stop();
|
||||
}
|
||||
void clearRecv(){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
}
|
||||
void clearSend(){
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
void send_Textfield_SendData(){
|
||||
if(send_flag==1){
|
||||
myServer.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
else if(send_flag==2){
|
||||
myClient.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : WiFi Server
|
||||
Description : Use ESP32's WiFi server feature to wait for other WiFi devices to connect.
|
||||
And communicate with them once a connection has been established.
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include <WiFi.h>
|
||||
|
||||
#define port 80
|
||||
const char *ssid_Router = "********"; //input your wifi name
|
||||
const char *password_Router = "********"; //input your wifi passwords
|
||||
WiFiServer server(port);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.printf("\nConnecting to ");
|
||||
Serial.println(ssid_Router);
|
||||
WiFi.disconnect();
|
||||
WiFi.begin(ssid_Router, password_Router);
|
||||
delay(1000);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected.");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.printf("IP port: %d\n",port);
|
||||
server.begin(port);
|
||||
WiFi.setAutoReconnect(true);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
WiFiClient client = server.accept(); // listen for incoming clients
|
||||
if (client) { // if you get a client,
|
||||
Serial.println("Client connected.");
|
||||
while (client.connected()) { // loop while the client's connected
|
||||
if (client.available()) { // if there's bytes to read from the client,
|
||||
Serial.println(client.readStringUntil('\n')); // print it out the serial monitor
|
||||
while(client.read()>0); // clear the wifi receive area cache
|
||||
}
|
||||
if(Serial.available()){ // if there's bytes to read from the serial monitor,
|
||||
client.print(Serial.readStringUntil('\n')); // print it out the client.
|
||||
while(Serial.read()>0); // clear the wifi receive area cache
|
||||
}
|
||||
}
|
||||
client.stop(); // stop the client connecting.
|
||||
Serial.println("Client Disconnected.");
|
||||
}
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch WiFi Client and Server
|
||||
* Author Zhentao Lin @ Freenove (http://www.freenove.com)
|
||||
* Date 2020/7/11
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to control a 2D ellipse through communicate to an
|
||||
* ESP32 board or other micro controller.
|
||||
* It will automatically detect and connect to a device (serial port) which
|
||||
* use the same trans format.
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import controlP5.*;
|
||||
import processing.net.*;
|
||||
|
||||
ControlP5 cp5;
|
||||
//Println console;
|
||||
Server myServer;
|
||||
Client myClient;
|
||||
int dataIn=0;
|
||||
int radioFlag1=0;
|
||||
int radioFlag2=0;
|
||||
int send_flag=1;
|
||||
|
||||
void setup() {
|
||||
size(600,400);
|
||||
smooth();
|
||||
noStroke();
|
||||
cp5 = new ControlP5(this);
|
||||
cp5.addTab("default")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setLabel("TCP Server")
|
||||
.setId(1)
|
||||
;
|
||||
cp5.getTab("TCP Client")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setId(2)
|
||||
;
|
||||
|
||||
cp5.addTextfield("Local IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addTextfield("Local PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("8888")
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addRadioButton("connect1")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("Listening", 1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("default")
|
||||
;
|
||||
|
||||
cp5.addTextfield("Remote IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("192.168.1.xxx")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addTextfield("Remote PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("80")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addRadioButton("connect2")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("connect Server",1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
|
||||
cp5.addTextarea("recvData")
|
||||
.setPosition(200,40)
|
||||
.setSize(350,150)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorBackground(color(100,255))
|
||||
.scroll(15)
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addTextfield("sendData")
|
||||
.setPosition(200,230)
|
||||
.setSize(350,80)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setLabel("")
|
||||
.setFocus(true)
|
||||
.setColorBackground(color(100,255))
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearRecv")
|
||||
.setValue(0)
|
||||
.setPosition(200,200)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearSend")
|
||||
.setValue(0)
|
||||
.setPosition(200,320)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("Send")
|
||||
.setValue(0)
|
||||
.setPosition(450,320)
|
||||
.setSize(100,20)
|
||||
.plugTo(this,"send_Textfield_SendData")
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
}
|
||||
|
||||
void draw(){
|
||||
background(220);
|
||||
if(radioFlag1==1){
|
||||
Client thisClient = myServer.available();
|
||||
if (thisClient !=null) {
|
||||
String whatClientSaid = thisClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(thisClient.ip()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// myServer.active()
|
||||
if(radioFlag2==1){
|
||||
if (myClient.available() > 0) {
|
||||
String whatClientSaid = myClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(cp5.get(Textfield.class,"Remote IP").getText()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void controlEvent(ControlEvent theControlEvent) {
|
||||
if (theControlEvent.isTab()) {
|
||||
if(theControlEvent.getTab().getId()==1){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=1;
|
||||
}
|
||||
else if(theControlEvent.getTab().getId()==2){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void connect1(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag1=a;
|
||||
if(radioFlag1==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Local PORT").getText();
|
||||
int port = int(port_buffer);
|
||||
myServer = new Server(this,port);
|
||||
println(Server.ip());
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
println(port);
|
||||
}
|
||||
else
|
||||
myServer.stop();
|
||||
}
|
||||
void connect2(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag2=a;
|
||||
if(radioFlag2==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Remote PORT").getText();
|
||||
String IP_buffer = cp5.get(Textfield.class,"Remote IP").getText();
|
||||
int port = int(port_buffer);
|
||||
if(IP_buffer.compareTo("192.168.1.xxx")==0){
|
||||
println("connect error!");
|
||||
}
|
||||
else{
|
||||
myClient = new Client(this,IP_buffer,port);
|
||||
println("connect success!");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
myClient.stop();
|
||||
}
|
||||
void clearRecv(){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
}
|
||||
void clearSend(){
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
void send_Textfield_SendData(){
|
||||
if(send_flag==1){
|
||||
myServer.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
else if(send_flag==2){
|
||||
myClient.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/**********************************************************************
|
||||
Filename : Camera Web Serrver
|
||||
Description : ESP32 connects to WiFi and prints a url through a serial port.
|
||||
Users visit the site to view the image data ESP32 camera.
|
||||
Auther : www.freenove.com
|
||||
Modification: 2024/06/20
|
||||
**********************************************************************/
|
||||
#include "esp_camera.h"
|
||||
#include <WiFi.h>
|
||||
|
||||
// ===================
|
||||
// Select camera model
|
||||
// ===================
|
||||
#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
||||
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
|
||||
//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
|
||||
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
|
||||
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
|
||||
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
|
||||
// ** Espressif Internal Boards **
|
||||
//#define CAMERA_MODEL_ESP32_CAM_BOARD
|
||||
//#define CAMERA_MODEL_ESP32S2_CAM_BOARD
|
||||
//#define CAMERA_MODEL_ESP32S3_CAM_LCD
|
||||
|
||||
|
||||
#include "camera_pins.h"
|
||||
|
||||
const char *ssid_Router = "********"; //input your wifi name
|
||||
const char *password_Router = "********"; //input your wifi passwords
|
||||
camera_config_t config;
|
||||
|
||||
void startCameraServer();
|
||||
void camera_init();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Serial.println();
|
||||
|
||||
camera_init();
|
||||
|
||||
// camera init
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
s->set_vflip(s, 0); //1-Upside down, 0-No operation
|
||||
s->set_hmirror(s, 0); //1-Reverse left and right, 0-No operation
|
||||
s->set_brightness(s, 1); //up the blightness just a bit
|
||||
s->set_saturation(s, -1); //lower the saturation
|
||||
|
||||
WiFi.begin(ssid_Router, password_Router);
|
||||
WiFi.setSleep(false);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
|
||||
startCameraServer();
|
||||
|
||||
Serial.print("Camera Ready! Use 'http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
Serial.println("' to connect");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
;
|
||||
}
|
||||
|
||||
void camera_init() {
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sccb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sccb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000;
|
||||
config.frame_size = FRAMESIZE_QVGA;
|
||||
config.pixel_format = PIXFORMAT_JPEG; // for streaming
|
||||
//config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
|
||||
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
|
||||
config.fb_location = CAMERA_FB_IN_PSRAM;
|
||||
config.jpeg_quality = 10;
|
||||
config.fb_count = 2;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,273 +0,0 @@
|
||||
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 37
|
||||
#define Y7_GPIO_NUM 38
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 35
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 13
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
|
||||
#define PWDN_GPIO_NUM 0
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD)
|
||||
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||
#define USE_BOARD_HEADER 0
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM 33
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 19
|
||||
#define Y7_GPIO_NUM 21
|
||||
#define Y6_GPIO_NUM 39
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y5_GPIO_NUM 13
|
||||
#else
|
||||
#define Y5_GPIO_NUM 35
|
||||
#endif
|
||||
#define Y4_GPIO_NUM 14
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y3_GPIO_NUM 35
|
||||
#else
|
||||
#define Y3_GPIO_NUM 13
|
||||
#endif
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 40
|
||||
#define SIOD_GPIO_NUM 17
|
||||
#define SIOC_GPIO_NUM 18
|
||||
|
||||
#define Y9_GPIO_NUM 39
|
||||
#define Y8_GPIO_NUM 41
|
||||
#define Y7_GPIO_NUM 42
|
||||
#define Y6_GPIO_NUM 12
|
||||
#define Y5_GPIO_NUM 3
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 47
|
||||
#define Y2_GPIO_NUM 13
|
||||
#define VSYNC_GPIO_NUM 21
|
||||
#define HREF_GPIO_NUM 38
|
||||
#define PCLK_GPIO_NUM 11
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD)
|
||||
// The 18 pin header on the board has Y5 and Y3 swapped
|
||||
#define USE_BOARD_HEADER 0
|
||||
#define PWDN_GPIO_NUM 1
|
||||
#define RESET_GPIO_NUM 2
|
||||
#define XCLK_GPIO_NUM 42
|
||||
#define SIOD_GPIO_NUM 41
|
||||
#define SIOC_GPIO_NUM 18
|
||||
|
||||
#define Y9_GPIO_NUM 16
|
||||
#define Y8_GPIO_NUM 39
|
||||
#define Y7_GPIO_NUM 40
|
||||
#define Y6_GPIO_NUM 15
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y5_GPIO_NUM 12
|
||||
#else
|
||||
#define Y5_GPIO_NUM 13
|
||||
#endif
|
||||
#define Y4_GPIO_NUM 5
|
||||
#if USE_BOARD_HEADER
|
||||
#define Y3_GPIO_NUM 13
|
||||
#else
|
||||
#define Y3_GPIO_NUM 12
|
||||
#endif
|
||||
#define Y2_GPIO_NUM 14
|
||||
#define VSYNC_GPIO_NUM 38
|
||||
#define HREF_GPIO_NUM 4
|
||||
#define PCLK_GPIO_NUM 3
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 15
|
||||
#define SIOD_GPIO_NUM 4
|
||||
#define SIOC_GPIO_NUM 5
|
||||
|
||||
#define Y2_GPIO_NUM 11
|
||||
#define Y3_GPIO_NUM 9
|
||||
#define Y4_GPIO_NUM 8
|
||||
#define Y5_GPIO_NUM 10
|
||||
#define Y6_GPIO_NUM 12
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y8_GPIO_NUM 17
|
||||
#define Y9_GPIO_NUM 16
|
||||
|
||||
#define VSYNC_GPIO_NUM 6
|
||||
#define HREF_GPIO_NUM 7
|
||||
#define PCLK_GPIO_NUM 13
|
||||
|
||||
#else
|
||||
#error "Camera model not selected"
|
||||
#endif
|
@ -1,88 +0,0 @@
|
||||
#include "esp_camera.h"
|
||||
#include <WiFi.h>
|
||||
//
|
||||
// WARNING!!! PSRAM IC required for UXGA resolution and high JPEG quality
|
||||
// Ensure ESP32 Wrover Module or other board with PSRAM is selected
|
||||
// Partial images will be transmitted if image exceeds buffer size
|
||||
//
|
||||
|
||||
// Select camera model
|
||||
#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
|
||||
|
||||
#include "camera_pins.h"
|
||||
|
||||
const char* ssid = "********"; //input your wifi name
|
||||
const char* password = "********"; //input your wifi passwords
|
||||
|
||||
void startCameraServer();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Serial.println();
|
||||
|
||||
camera_config_t config;
|
||||
config.ledc_channel = LEDC_CHANNEL_0;
|
||||
config.ledc_timer = LEDC_TIMER_0;
|
||||
config.pin_d0 = Y2_GPIO_NUM;
|
||||
config.pin_d1 = Y3_GPIO_NUM;
|
||||
config.pin_d2 = Y4_GPIO_NUM;
|
||||
config.pin_d3 = Y5_GPIO_NUM;
|
||||
config.pin_d4 = Y6_GPIO_NUM;
|
||||
config.pin_d5 = Y7_GPIO_NUM;
|
||||
config.pin_d6 = Y8_GPIO_NUM;
|
||||
config.pin_d7 = Y9_GPIO_NUM;
|
||||
config.pin_xclk = XCLK_GPIO_NUM;
|
||||
config.pin_pclk = PCLK_GPIO_NUM;
|
||||
config.pin_vsync = VSYNC_GPIO_NUM;
|
||||
config.pin_href = HREF_GPIO_NUM;
|
||||
config.pin_sccb_sda = SIOD_GPIO_NUM;
|
||||
config.pin_sccb_scl = SIOC_GPIO_NUM;
|
||||
config.pin_pwdn = PWDN_GPIO_NUM;
|
||||
config.pin_reset = RESET_GPIO_NUM;
|
||||
config.xclk_freq_hz = 20000000;
|
||||
config.pixel_format = PIXFORMAT_JPEG;
|
||||
|
||||
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
|
||||
// for larger pre-allocated frame buffer.
|
||||
if(psramFound()){
|
||||
config.frame_size = FRAMESIZE_UXGA;
|
||||
config.jpeg_quality = 10;
|
||||
config.fb_count = 2;
|
||||
} else {
|
||||
config.frame_size = FRAMESIZE_SVGA;
|
||||
config.jpeg_quality = 12;
|
||||
config.fb_count = 1;
|
||||
}
|
||||
|
||||
// camera init
|
||||
esp_err_t err = esp_camera_init(&config);
|
||||
if (err != ESP_OK) {
|
||||
Serial.printf("Camera init failed with error 0x%x", err);
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
// drop down frame size for higher initial frame rate
|
||||
s->set_framesize(s, FRAMESIZE_VGA);
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected");
|
||||
|
||||
startCameraServer();
|
||||
|
||||
Serial.print("Camera Ready! Use 'http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
Serial.println("' to connect");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
delay(10000);
|
||||
}
|
@ -1,267 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_camera.h"
|
||||
#include "img_converters.h"
|
||||
#include "fb_gfx.h"
|
||||
#include "driver/ledc.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_ARDUHAL_ESP_LOG)
|
||||
#include "esp32-hal-log.h"
|
||||
#define TAG ""
|
||||
#else
|
||||
#include "esp_log.h"
|
||||
static const char *TAG = "camera_httpd";
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
httpd_req_t *req;
|
||||
size_t len;
|
||||
} jpg_chunking_t;
|
||||
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
static const char *_STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
|
||||
static const char *_STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
|
||||
static const char *_STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %d.%06d\r\n\r\n";
|
||||
|
||||
httpd_handle_t stream_httpd = NULL;
|
||||
httpd_handle_t camera_httpd = NULL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t size; // number of values used for filtering
|
||||
size_t index; // current value index
|
||||
size_t count; // value count
|
||||
int sum;
|
||||
int *values; // array to be filled with values
|
||||
} ra_filter_t;
|
||||
|
||||
static ra_filter_t ra_filter;
|
||||
|
||||
static ra_filter_t *ra_filter_init(ra_filter_t *filter, size_t sample_size)
|
||||
{
|
||||
memset(filter, 0, sizeof(ra_filter_t));
|
||||
|
||||
filter->values = (int *)malloc(sample_size * sizeof(int));
|
||||
if (!filter->values)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(filter->values, 0, sample_size * sizeof(int));
|
||||
|
||||
filter->size = sample_size;
|
||||
return filter;
|
||||
}
|
||||
|
||||
static int ra_filter_run(ra_filter_t *filter, int value)
|
||||
{
|
||||
if (!filter->values)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
filter->sum -= filter->values[filter->index];
|
||||
filter->values[filter->index] = value;
|
||||
filter->sum += filter->values[filter->index];
|
||||
filter->index++;
|
||||
filter->index = filter->index % filter->size;
|
||||
if (filter->count < filter->size)
|
||||
{
|
||||
filter->count++;
|
||||
}
|
||||
return filter->sum / filter->count;
|
||||
}
|
||||
|
||||
static esp_err_t stream_handler(httpd_req_t *req)
|
||||
{
|
||||
camera_fb_t *fb = NULL;
|
||||
struct timeval _timestamp;
|
||||
esp_err_t res = ESP_OK;
|
||||
size_t _jpg_buf_len = 0;
|
||||
uint8_t *_jpg_buf = NULL;
|
||||
char *part_buf[128];
|
||||
|
||||
static int64_t last_frame = 0;
|
||||
if (!last_frame)
|
||||
{
|
||||
last_frame = esp_timer_get_time();
|
||||
}
|
||||
|
||||
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
|
||||
if (res != ESP_OK)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_hdr(req, "X-Framerate", "60");
|
||||
|
||||
while (true)
|
||||
{
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb)
|
||||
{
|
||||
ESP_LOGE(TAG, "Camera capture failed");
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
_timestamp.tv_sec = fb->timestamp.tv_sec;
|
||||
_timestamp.tv_usec = fb->timestamp.tv_usec;
|
||||
if (fb->format != PIXFORMAT_JPEG)
|
||||
{
|
||||
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
if (!jpeg_converted)
|
||||
{
|
||||
ESP_LOGE(TAG, "JPEG compression failed");
|
||||
res = ESP_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_jpg_buf_len = fb->len;
|
||||
_jpg_buf = fb->buf;
|
||||
}
|
||||
}
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||
}
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
size_t hlen = snprintf((char *)part_buf, 128, _STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec);
|
||||
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
|
||||
}
|
||||
if (res == ESP_OK)
|
||||
{
|
||||
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
|
||||
}
|
||||
if (fb)
|
||||
{
|
||||
esp_camera_fb_return(fb);
|
||||
fb = NULL;
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
else if (_jpg_buf)
|
||||
{
|
||||
free(_jpg_buf);
|
||||
_jpg_buf = NULL;
|
||||
}
|
||||
if (res != ESP_OK)
|
||||
{
|
||||
ESP_LOGI(TAG, "res != ESP_OK : %d , break!", res);
|
||||
break;
|
||||
}
|
||||
int64_t fr_end = esp_timer_get_time();
|
||||
|
||||
int64_t frame_time = fr_end - last_frame;
|
||||
last_frame = fr_end;
|
||||
frame_time /= 1000;
|
||||
uint32_t avg_frame_time = ra_filter_run(&ra_filter, frame_time);
|
||||
ESP_LOGI(TAG, "MJPG: %uB %ums (%.1ffps), AVG: %ums (%.1ffps)",
|
||||
(uint32_t)(_jpg_buf_len),
|
||||
(uint32_t)frame_time, 1000.0 / (uint32_t)frame_time,
|
||||
avg_frame_time, 1000.0 / avg_frame_time);
|
||||
}
|
||||
ESP_LOGI(TAG, "Stream exit!");
|
||||
last_frame = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t parse_get(httpd_req_t *req, char **obuf)
|
||||
{
|
||||
char *buf = NULL;
|
||||
size_t buf_len = 0;
|
||||
|
||||
buf_len = httpd_req_get_url_query_len(req) + 1;
|
||||
if (buf_len > 1)
|
||||
{
|
||||
buf = (char *)malloc(buf_len);
|
||||
if (!buf)
|
||||
{
|
||||
httpd_resp_send_500(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK)
|
||||
{
|
||||
*obuf = buf;
|
||||
return ESP_OK;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
httpd_resp_send_404(req);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
const char index_web[] =
|
||||
"\
|
||||
<html>\
|
||||
<head>\
|
||||
<title>Video Streaming Demonstration</title>\
|
||||
</head>\
|
||||
<body>\
|
||||
<h1>Video Streaming Demonstration</h1>\
|
||||
<img src=\"/stream\"\ style=\"transform:rotate(180deg)\"/>\
|
||||
</body>\
|
||||
</html>\
|
||||
";
|
||||
|
||||
static esp_err_t index_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "text/html");
|
||||
// httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
|
||||
sensor_t *s = esp_camera_sensor_get();
|
||||
if (s != NULL)
|
||||
{
|
||||
// return httpd_resp_sendstr(req, (const char *)index_web);
|
||||
return httpd_resp_send(req, (const char *)index_web, sizeof(index_web));
|
||||
// return httpd_resp_send(req, (const char *)index_ov2640_html_gz, index_ov2640_html_gz_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Camera sensor not found");
|
||||
return httpd_resp_send_500(req);
|
||||
}
|
||||
}
|
||||
|
||||
void startCameraServer()
|
||||
{
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.max_uri_handlers = 16;
|
||||
|
||||
httpd_uri_t index_uri = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = index_handler,
|
||||
.user_ctx = NULL};
|
||||
|
||||
httpd_uri_t stream_uri = {
|
||||
.uri = "/stream",
|
||||
.method = HTTP_GET,
|
||||
.handler = stream_handler,
|
||||
.user_ctx = NULL};
|
||||
ra_filter_init(&ra_filter, 20);
|
||||
|
||||
ESP_LOGI(TAG, "Starting web server on port: '%d'", config.server_port);
|
||||
if (httpd_start(&camera_httpd, &config) == ESP_OK)
|
||||
{
|
||||
httpd_register_uri_handler(camera_httpd, &index_uri);
|
||||
httpd_register_uri_handler(camera_httpd, &stream_uri);
|
||||
}
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_ESP_EYE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 4
|
||||
#define SIOD_GPIO_NUM 18
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 36
|
||||
#define Y8_GPIO_NUM 37
|
||||
#define Y7_GPIO_NUM 38
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 35
|
||||
#define Y4_GPIO_NUM 14
|
||||
#define Y3_GPIO_NUM 13
|
||||
#define Y2_GPIO_NUM 34
|
||||
#define VSYNC_GPIO_NUM 5
|
||||
#define HREF_GPIO_NUM 27
|
||||
#define PCLK_GPIO_NUM 25
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 22
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM 32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 0
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 21
|
||||
#define Y4_GPIO_NUM 19
|
||||
#define Y3_GPIO_NUM 18
|
||||
#define Y2_GPIO_NUM 5
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
|
||||
#define PWDN_GPIO_NUM 0
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 17
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
#else
|
||||
#error "Camera model not selected"
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 68 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 241 KiB |
Binary file not shown.
Before Width: | Height: | Size: 323 KiB |
58
LICENSE.txt
58
LICENSE.txt
@ -1,58 +0,0 @@
|
||||
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License (CC BY-NC-SA 3.0)
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
|
||||
"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(g) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
|
||||
"Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
|
||||
"License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, Noncommercial, ShareAlike.
|
||||
"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
|
||||
"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
|
||||
"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
|
||||
"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
|
||||
"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
|
||||
"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
|
||||
|
||||
to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
|
||||
to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
|
||||
to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
|
||||
to Distribute and Publicly Perform Adaptations.
|
||||
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights described in Section 4(e).
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
|
||||
|
||||
You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(d), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(d), as requested.
|
||||
You may Distribute or Publicly Perform an Adaptation only under: (i) the terms of this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-NonCommercial-ShareAlike 3.0 US) ("Applicable License"). You must include a copy of, or the URI, for Applicable License with every copy of each Adaptation You Distribute or Publicly Perform. You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License. You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.
|
||||
You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in con-nection with the exchange of copyrighted works.
|
||||
If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(d) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
|
||||
For the avoidance of doubt:
|
||||
|
||||
Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
|
||||
Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and,
|
||||
Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c).
|
||||
Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING AND TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THIS EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
|
||||
Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
|
||||
8. Miscellaneous
|
||||
|
||||
Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
|
||||
Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
|
||||
If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
|
||||
This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
|
||||
The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
|
BIN
Part list.jpg
BIN
Part list.jpg
Binary file not shown.
Before Width: | Height: | Size: 848 KiB |
@ -1,2 +0,0 @@
|
||||
|
||||
print('Hello World!\n')
|
@ -1,30 +0,0 @@
|
||||
#!/opt/bin/lv_micropython
|
||||
import uos as os
|
||||
import uerrno as errno
|
||||
iter = os.ilistdir()
|
||||
IS_DIR = 0x4000
|
||||
IS_REGULAR = 0x8000
|
||||
|
||||
while True:
|
||||
try:
|
||||
entry = next(iter)
|
||||
filename = entry[0]
|
||||
file_type = entry[1]
|
||||
if filename == 'boot.py':
|
||||
continue
|
||||
else:
|
||||
print("===============================")
|
||||
print(filename,end="")
|
||||
if file_type == IS_DIR:
|
||||
print(", File is a directory")
|
||||
print("===============================")
|
||||
else:
|
||||
print("\n===============================")
|
||||
#print("Contents:")
|
||||
#with open(filename) as f:
|
||||
# for line in enumerate(f):
|
||||
# print("{}".format(line[1]),end="")
|
||||
#print("")
|
||||
exec(open(filename).read(),globals())
|
||||
except StopIteration:
|
||||
break
|
@ -1,17 +0,0 @@
|
||||
from time import sleep_ms
|
||||
from machine import Pin
|
||||
|
||||
led=Pin(2,Pin.OUT) #create LED object from pin2,Set Pin2 to output
|
||||
try:
|
||||
while True:
|
||||
led.value(1) #Set led turn on
|
||||
sleep_ms(1000)
|
||||
led.value(0) #Set led turn off
|
||||
sleep_ms(1000)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,100 +0,0 @@
|
||||
# This example demonstrates a UART periperhal.
|
||||
|
||||
import bluetooth
|
||||
import random
|
||||
import struct
|
||||
import time
|
||||
from ble_advertising import advertising_payload
|
||||
|
||||
from micropython import const
|
||||
|
||||
_IRQ_CENTRAL_CONNECT = const(1)
|
||||
_IRQ_CENTRAL_DISCONNECT = const(2)
|
||||
_IRQ_GATTS_WRITE = const(3)
|
||||
|
||||
_FLAG_READ = const(0x0002)
|
||||
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
|
||||
_FLAG_WRITE = const(0x0008)
|
||||
_FLAG_NOTIFY = const(0x0010)
|
||||
|
||||
_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
|
||||
_UART_TX = (
|
||||
bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
|
||||
_FLAG_READ | _FLAG_NOTIFY,
|
||||
)
|
||||
_UART_RX = (
|
||||
bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
|
||||
_FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
|
||||
)
|
||||
_UART_SERVICE = (
|
||||
_UART_UUID,
|
||||
(_UART_TX, _UART_RX),
|
||||
)
|
||||
|
||||
|
||||
class BLESimplePeripheral:
|
||||
def __init__(self, ble, name="ESP32"):
|
||||
self._ble = ble
|
||||
self._ble.active(True)
|
||||
self._ble.irq(self._irq)
|
||||
((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
|
||||
self._connections = set()
|
||||
self._write_callback = None
|
||||
self._payload = advertising_payload(name=name, services=[_UART_UUID])
|
||||
self._advertise()
|
||||
|
||||
def _irq(self, event, data):
|
||||
# Track connections so we can send notifications.
|
||||
if event == _IRQ_CENTRAL_CONNECT:
|
||||
conn_handle, _, _ = data
|
||||
print("New connection", conn_handle)
|
||||
print("\nThe BLE connection is successful.")
|
||||
self._connections.add(conn_handle)
|
||||
elif event == _IRQ_CENTRAL_DISCONNECT:
|
||||
conn_handle, _, _ = data
|
||||
print("Disconnected", conn_handle)
|
||||
self._connections.remove(conn_handle)
|
||||
# Start advertising again to allow a new connection.
|
||||
self._advertise()
|
||||
elif event == _IRQ_GATTS_WRITE:
|
||||
conn_handle, value_handle = data
|
||||
value = self._ble.gatts_read(value_handle)
|
||||
if value_handle == self._handle_rx and self._write_callback:
|
||||
self._write_callback(value)
|
||||
|
||||
def send(self, data):
|
||||
for conn_handle in self._connections:
|
||||
self._ble.gatts_notify(conn_handle, self._handle_tx, data)
|
||||
|
||||
def is_connected(self):
|
||||
return len(self._connections) > 0
|
||||
|
||||
def _advertise(self, interval_us=500000):
|
||||
print("Starting advertising")
|
||||
self._ble.gap_advertise(interval_us, adv_data=self._payload)
|
||||
|
||||
def on_write(self, callback):
|
||||
self._write_callback = callback
|
||||
|
||||
|
||||
def demo():
|
||||
ble = bluetooth.BLE()
|
||||
p = BLESimplePeripheral(ble)
|
||||
|
||||
def on_rx(rx_data):
|
||||
print("RX", rx_data)
|
||||
|
||||
p.on_write(on_rx)
|
||||
|
||||
print("Please use LightBlue to connect to ESP32.")
|
||||
|
||||
while True:
|
||||
if p.is_connected():
|
||||
# Short burst of queued notifications.
|
||||
tx_data = input("Enter anything: ")
|
||||
print("Send: ", tx_data)
|
||||
p.send(tx_data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo()
|
@ -1,93 +0,0 @@
|
||||
# Helpers for generating BLE advertising payloads.
|
||||
|
||||
from micropython import const
|
||||
import struct
|
||||
import bluetooth
|
||||
|
||||
# Advertising payloads are repeated packets of the following form:
|
||||
# 1 byte data length (N + 1)
|
||||
# 1 byte type (see constants below)
|
||||
# N bytes type-specific data
|
||||
|
||||
_ADV_TYPE_FLAGS = const(0x01)
|
||||
_ADV_TYPE_NAME = const(0x09)
|
||||
_ADV_TYPE_UUID16_COMPLETE = const(0x3)
|
||||
_ADV_TYPE_UUID32_COMPLETE = const(0x5)
|
||||
_ADV_TYPE_UUID128_COMPLETE = const(0x7)
|
||||
_ADV_TYPE_UUID16_MORE = const(0x2)
|
||||
_ADV_TYPE_UUID32_MORE = const(0x4)
|
||||
_ADV_TYPE_UUID128_MORE = const(0x6)
|
||||
_ADV_TYPE_APPEARANCE = const(0x19)
|
||||
|
||||
|
||||
# Generate a payload to be passed to gap_advertise(adv_data=...).
|
||||
def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0):
|
||||
payload = bytearray()
|
||||
|
||||
def _append(adv_type, value):
|
||||
nonlocal payload
|
||||
payload += struct.pack("BB", len(value) + 1, adv_type) + value
|
||||
|
||||
_append(
|
||||
_ADV_TYPE_FLAGS,
|
||||
struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)),
|
||||
)
|
||||
|
||||
if name:
|
||||
_append(_ADV_TYPE_NAME, name)
|
||||
|
||||
if services:
|
||||
for uuid in services:
|
||||
b = bytes(uuid)
|
||||
if len(b) == 2:
|
||||
_append(_ADV_TYPE_UUID16_COMPLETE, b)
|
||||
elif len(b) == 4:
|
||||
_append(_ADV_TYPE_UUID32_COMPLETE, b)
|
||||
elif len(b) == 16:
|
||||
_append(_ADV_TYPE_UUID128_COMPLETE, b)
|
||||
|
||||
# See org.bluetooth.characteristic.gap.appearance.xml
|
||||
if appearance:
|
||||
_append(_ADV_TYPE_APPEARANCE, struct.pack("<h", appearance))
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
def decode_field(payload, adv_type):
|
||||
i = 0
|
||||
result = []
|
||||
while i + 1 < len(payload):
|
||||
if payload[i + 1] == adv_type:
|
||||
result.append(payload[i + 2 : i + payload[i] + 1])
|
||||
i += 1 + payload[i]
|
||||
return result
|
||||
|
||||
|
||||
def decode_name(payload):
|
||||
n = decode_field(payload, _ADV_TYPE_NAME)
|
||||
return str(n[0], "utf-8") if n else ""
|
||||
|
||||
|
||||
def decode_services(payload):
|
||||
services = []
|
||||
for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE):
|
||||
services.append(bluetooth.UUID(struct.unpack("<h", u)[0]))
|
||||
for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE):
|
||||
services.append(bluetooth.UUID(struct.unpack("<d", u)[0]))
|
||||
for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE):
|
||||
services.append(bluetooth.UUID(u))
|
||||
return services
|
||||
|
||||
|
||||
def demo():
|
||||
payload = advertising_payload(
|
||||
name="micropython",
|
||||
services=[bluetooth.UUID(0x181A), bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")],
|
||||
)
|
||||
print(payload)
|
||||
print(decode_name(payload))
|
||||
print(decode_services(payload))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo()
|
@ -1,25 +0,0 @@
|
||||
import time
|
||||
import network
|
||||
|
||||
ssidRouter = '********' #Enter the router name
|
||||
passwordRouter = '********' #Enter the router password
|
||||
|
||||
def STA_Setup(ssidRouter,passwordRouter):
|
||||
print("Setup start")
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
if not sta_if.isconnected():
|
||||
print('connecting to',ssidRouter)
|
||||
sta_if.active(True)
|
||||
sta_if.connect(ssidRouter,passwordRouter)
|
||||
while not sta_if.isconnected():
|
||||
pass
|
||||
print('Connected, IP address:', sta_if.ifconfig())
|
||||
print("Setup End")
|
||||
|
||||
try:
|
||||
STA_Setup(ssidRouter,passwordRouter)
|
||||
except:
|
||||
sta_if.disconnect()
|
||||
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
import network
|
||||
|
||||
ssidAP = 'WiFi_Name' #Enter the router name
|
||||
passwordAP = '12345678' #Enter the router password
|
||||
|
||||
local_IP = '192.168.1.10'
|
||||
gateway = '192.168.1.1'
|
||||
subnet = '255.255.255.0'
|
||||
dns = '8.8.8.8'
|
||||
|
||||
ap_if = network.WLAN(network.AP_IF)
|
||||
|
||||
def AP_Setup(ssidAP,passwordAP):
|
||||
ap_if.ifconfig([local_IP,gateway,subnet,dns])
|
||||
print("Setting soft-AP ... ")
|
||||
ap_if.config(essid=ssidAP,authmode=network.AUTH_WPA_WPA2_PSK, password=passwordAP)
|
||||
ap_if.active(True)
|
||||
print('Success, IP address:', ap_if.ifconfig())
|
||||
print("Setup End\n")
|
||||
|
||||
try:
|
||||
AP_Setup(ssidAP,passwordAP)
|
||||
except:
|
||||
print("Failed, please disconnect the power and restart the operation.")
|
||||
ap_if.disconnect()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,42 +0,0 @@
|
||||
import network
|
||||
|
||||
ssidRouter = '********' #Enter the router name
|
||||
passwordRouter = '********' #Enter the router password
|
||||
|
||||
ssidAP = 'WiFi_Name'#Enter the AP name
|
||||
passwordAP = '12345678' #Enter the AP password
|
||||
|
||||
local_IP = '192.168.4.150'
|
||||
gateway = '192.168.4.1'
|
||||
subnet = '255.255.255.0'
|
||||
dns = '8.8.8.8'
|
||||
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
ap_if = network.WLAN(network.AP_IF)
|
||||
|
||||
def STA_Setup(ssidRouter,passwordRouter):
|
||||
print("Setting soft-STA ... ")
|
||||
if not sta_if.isconnected():
|
||||
print('connecting to',ssidRouter)
|
||||
sta_if.active(True)
|
||||
sta_if.connect(ssidRouter,passwordRouter)
|
||||
while not sta_if.isconnected():
|
||||
pass
|
||||
print('Connected, IP address:', sta_if.ifconfig())
|
||||
print("Setup End")
|
||||
|
||||
def AP_Setup(ssidAP,passwordAP):
|
||||
ap_if.ifconfig([local_IP,gateway,subnet,dns])
|
||||
print("Setting soft-AP ... ")
|
||||
ap_if.config(essid=ssidAP,authmode=network.AUTH_WPA_WPA2_PSK, password=passwordAP)
|
||||
ap_if.active(True)
|
||||
print('Success, IP address:', ap_if.ifconfig())
|
||||
print("Setup End\n")
|
||||
|
||||
try:
|
||||
AP_Setup(ssidAP,passwordAP)
|
||||
STA_Setup(ssidRouter,passwordRouter)
|
||||
except:
|
||||
sta_if.disconnect()
|
||||
ap_if.disconnect()
|
||||
|
@ -1,43 +0,0 @@
|
||||
import network
|
||||
import socket
|
||||
import time
|
||||
|
||||
ssidRouter = "********" #Enter the router name
|
||||
passwordRouter = "********" #Enter the router password
|
||||
host = "192.168.1.142" #input the remote server
|
||||
port = 8888 #input the remote port
|
||||
|
||||
wlan=None
|
||||
s=None
|
||||
|
||||
def connectWifi(ssid,passwd):
|
||||
global wlan
|
||||
wlan=network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
wlan.disconnect()
|
||||
wlan.connect(ssid,passwd)
|
||||
while(wlan.ifconfig()[0]=='0.0.0.0'):
|
||||
time.sleep(1)
|
||||
return True
|
||||
try:
|
||||
connectWifi(ssidRouter,passwordRouter)
|
||||
s = socket.socket()
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
s.connect((host,port))
|
||||
print("TCP Connected to:", host, ":", port)
|
||||
s.send('Hello')
|
||||
s.send('This is my IP.')
|
||||
while True:
|
||||
data = s.recv(1024)
|
||||
if(len(data) == 0):
|
||||
print("Close socket")
|
||||
s.close()
|
||||
break
|
||||
print(data)
|
||||
ret=s.send(data)
|
||||
except:
|
||||
print("TCP close, please reset!")
|
||||
if (s):
|
||||
s.close()
|
||||
wlan.disconnect()
|
||||
wlan.active(False)
|
@ -1,240 +0,0 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch WiFi Client and Server
|
||||
* Author Zhentao Lin @ Freenove (http://www.freenove.com)
|
||||
* Date 2020/7/11
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to control a 2D ellipse through communicate to an
|
||||
* ESP32 board or other micro controller.
|
||||
* It will automatically detect and connect to a device (serial port) which
|
||||
* use the same trans format.
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import controlP5.*;
|
||||
import processing.net.*;
|
||||
|
||||
ControlP5 cp5;
|
||||
//Println console;
|
||||
Server myServer;
|
||||
Client myClient;
|
||||
int dataIn=0;
|
||||
int radioFlag1=0;
|
||||
int radioFlag2=0;
|
||||
int send_flag=1;
|
||||
|
||||
void setup() {
|
||||
size(600,400);
|
||||
smooth();
|
||||
noStroke();
|
||||
cp5 = new ControlP5(this);
|
||||
cp5.addTab("default")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setLabel("TCP Server")
|
||||
.setId(1)
|
||||
;
|
||||
cp5.getTab("TCP Client")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setId(2)
|
||||
;
|
||||
|
||||
cp5.addTextfield("Local IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addTextfield("Local PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("8888")
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addRadioButton("connect1")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("Listening", 1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("default")
|
||||
;
|
||||
|
||||
cp5.addTextfield("Remote IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("192.168.1.xxx")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addTextfield("Remote PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("8000")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addRadioButton("connect2")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("connect Server",1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
|
||||
cp5.addTextarea("recvData")
|
||||
.setPosition(200,40)
|
||||
.setSize(350,150)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorBackground(color(100,255))
|
||||
.scroll(15)
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addTextfield("sendData")
|
||||
.setPosition(200,230)
|
||||
.setSize(350,80)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setLabel("")
|
||||
.setFocus(true)
|
||||
.setColorBackground(color(100,255))
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearRecv")
|
||||
.setValue(0)
|
||||
.setPosition(200,200)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearSend")
|
||||
.setValue(0)
|
||||
.setPosition(200,320)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("Send")
|
||||
.setValue(0)
|
||||
.setPosition(450,320)
|
||||
.setSize(100,20)
|
||||
.plugTo(this,"send_Textfield_SendData")
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
}
|
||||
|
||||
void draw(){
|
||||
background(220);
|
||||
if(radioFlag1==1){
|
||||
Client thisClient = myServer.available();
|
||||
if (thisClient !=null) {
|
||||
String whatClientSaid = thisClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(thisClient.ip()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// myServer.active()
|
||||
if(radioFlag2==1){
|
||||
if (myClient.available() > 0) {
|
||||
String whatClientSaid = myClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(cp5.get(Textfield.class,"Remote IP").getText()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void controlEvent(ControlEvent theControlEvent) {
|
||||
if (theControlEvent.isTab()) {
|
||||
if(theControlEvent.getTab().getId()==1){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=1;
|
||||
}
|
||||
else if(theControlEvent.getTab().getId()==2){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void connect1(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag1=a;
|
||||
if(radioFlag1==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Local PORT").getText();
|
||||
int port = int(port_buffer);
|
||||
myServer = new Server(this,port);
|
||||
println(Server.ip());
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
println(port);
|
||||
}
|
||||
else
|
||||
myServer.stop();
|
||||
}
|
||||
void connect2(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag2=a;
|
||||
if(radioFlag2==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Remote PORT").getText();
|
||||
String IP_buffer = cp5.get(Textfield.class,"Remote IP").getText();
|
||||
int port = int(port_buffer);
|
||||
if(IP_buffer.compareTo("192.168.1.xxx")==0){
|
||||
println("connect error!");
|
||||
}
|
||||
else{
|
||||
myClient = new Client(this,IP_buffer,port);
|
||||
println("connect success!");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
myClient.stop();
|
||||
}
|
||||
void clearRecv(){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
}
|
||||
void clearSend(){
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
void send_Textfield_SendData(){
|
||||
if(send_flag==1){
|
||||
myServer.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
else if(send_flag==2){
|
||||
myClient.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import network
|
||||
import socket
|
||||
import time
|
||||
|
||||
ssidRouter = "********" #Enter the router name
|
||||
passwordRouter = "********" #Enter the router password
|
||||
port = 8000 #input the remote port
|
||||
wlan=None
|
||||
listenSocket=None
|
||||
|
||||
def connectWifi(ssid,passwd):
|
||||
global wlan
|
||||
wlan=network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
wlan.disconnect()
|
||||
wlan.connect(ssid,passwd)
|
||||
while(wlan.ifconfig()[0]=='0.0.0.0'):
|
||||
time.sleep(1)
|
||||
return True
|
||||
|
||||
try:
|
||||
connectWifi(ssidRouter,passwordRouter)
|
||||
ip=wlan.ifconfig()[0]
|
||||
listenSocket = socket.socket()
|
||||
listenSocket.bind((ip,port))
|
||||
listenSocket.listen(1)
|
||||
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
print ('tcp waiting...')
|
||||
while True:
|
||||
print("Server IP:",ip,"\tPort:",port)
|
||||
print("accepting.....")
|
||||
conn,addr = listenSocket.accept()
|
||||
print(addr,"connected")
|
||||
break
|
||||
conn.send('I am Server')
|
||||
while True:
|
||||
data = conn.recv(1024)
|
||||
if(len(data) == 0):
|
||||
print("close socket")
|
||||
listenSocket.close()
|
||||
wlan.disconnect()
|
||||
wlan.active(False)
|
||||
break
|
||||
else:
|
||||
print(data)
|
||||
ret = conn.send(data)
|
||||
except:
|
||||
print("Close TCP-Server, please reset.")
|
||||
if(listenSocket):
|
||||
listenSocket.close()
|
||||
wlan.disconnect()
|
||||
wlan.active(False)
|
||||
|
||||
|
@ -1,240 +0,0 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Sketch WiFi Client and Server
|
||||
* Author Zhentao Lin @ Freenove (http://www.freenove.com)
|
||||
* Date 2020/7/11
|
||||
******************************************************************************
|
||||
* Brief
|
||||
* This sketch is used to control a 2D ellipse through communicate to an
|
||||
* ESP32 board or other micro controller.
|
||||
* It will automatically detect and connect to a device (serial port) which
|
||||
* use the same trans format.
|
||||
******************************************************************************
|
||||
* Copyright
|
||||
* Copyright © Freenove (http://www.freenove.com)
|
||||
* License
|
||||
* Creative Commons Attribution ShareAlike 3.0
|
||||
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
|
||||
******************************************************************************
|
||||
*/
|
||||
import controlP5.*;
|
||||
import processing.net.*;
|
||||
|
||||
ControlP5 cp5;
|
||||
//Println console;
|
||||
Server myServer;
|
||||
Client myClient;
|
||||
int dataIn=0;
|
||||
int radioFlag1=0;
|
||||
int radioFlag2=0;
|
||||
int send_flag=1;
|
||||
|
||||
void setup() {
|
||||
size(600,400);
|
||||
smooth();
|
||||
noStroke();
|
||||
cp5 = new ControlP5(this);
|
||||
cp5.addTab("default")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setLabel("TCP Server")
|
||||
.setId(1)
|
||||
;
|
||||
cp5.getTab("TCP Client")
|
||||
.activateEvent(true)
|
||||
.setHeight(30)
|
||||
.setWidth(100)
|
||||
.setId(2)
|
||||
;
|
||||
|
||||
cp5.addTextfield("Local IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addTextfield("Local PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("8888")
|
||||
.moveTo("default")
|
||||
;
|
||||
cp5.addRadioButton("connect1")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("Listening", 1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("default")
|
||||
;
|
||||
|
||||
cp5.addTextfield("Remote IP")
|
||||
.setPosition(20,40)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("192.168.1.xxx")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addTextfield("Remote PORT")
|
||||
.setPosition(20,120)
|
||||
.setSize(160,40)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorLabel(color(0))
|
||||
.setColorBackground(color(100,255))
|
||||
.setText("8000")
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
cp5.addRadioButton("connect2")
|
||||
.setPosition(20,200)
|
||||
.setSize(100,25)
|
||||
.addItem("connect Server",1)
|
||||
.setColorLabel(color(0))
|
||||
.moveTo("TCP Client")
|
||||
;
|
||||
|
||||
cp5.addTextarea("recvData")
|
||||
.setPosition(200,40)
|
||||
.setSize(350,150)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setColorBackground(color(100,255))
|
||||
.scroll(15)
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addTextfield("sendData")
|
||||
.setPosition(200,230)
|
||||
.setSize(350,80)
|
||||
.setFont(createFont("微软雅黑 Light",20))
|
||||
.setColor(color(255,255,0))
|
||||
.setLabel("")
|
||||
.setFocus(true)
|
||||
.setColorBackground(color(100,255))
|
||||
.setColorForeground(color(0,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearRecv")
|
||||
.setValue(0)
|
||||
.setPosition(200,200)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("clearSend")
|
||||
.setValue(0)
|
||||
.setPosition(200,320)
|
||||
.setSize(100,20)
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.addButton("Send")
|
||||
.setValue(0)
|
||||
.setPosition(450,320)
|
||||
.setSize(100,20)
|
||||
.plugTo(this,"send_Textfield_SendData")
|
||||
.setColorLabel(color(255,100))
|
||||
.moveTo("global")
|
||||
;
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
}
|
||||
|
||||
void draw(){
|
||||
background(220);
|
||||
if(radioFlag1==1){
|
||||
Client thisClient = myServer.available();
|
||||
if (thisClient !=null) {
|
||||
String whatClientSaid = thisClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(thisClient.ip()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// myServer.active()
|
||||
if(radioFlag2==1){
|
||||
if (myClient.available() > 0) {
|
||||
String whatClientSaid = myClient.readString();
|
||||
if (whatClientSaid != null) {
|
||||
cp5.get(Textarea.class,"recvData").append(cp5.get(Textfield.class,"Remote IP").getText()+": ");
|
||||
cp5.get(Textarea.class,"recvData").append(whatClientSaid+"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void controlEvent(ControlEvent theControlEvent) {
|
||||
if (theControlEvent.isTab()) {
|
||||
if(theControlEvent.getTab().getId()==1){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=1;
|
||||
}
|
||||
else if(theControlEvent.getTab().getId()==2){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
send_flag=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void connect1(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag1=a;
|
||||
if(radioFlag1==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Local PORT").getText();
|
||||
int port = int(port_buffer);
|
||||
myServer = new Server(this,port);
|
||||
println(Server.ip());
|
||||
cp5.get(Textfield.class,"Local IP").setText(Server.ip());
|
||||
println(port);
|
||||
}
|
||||
else
|
||||
myServer.stop();
|
||||
}
|
||||
void connect2(int a) {
|
||||
println("a radio Button event: "+a);
|
||||
radioFlag2=a;
|
||||
if(radioFlag2==1){
|
||||
String port_buffer = cp5.get(Textfield.class,"Remote PORT").getText();
|
||||
String IP_buffer = cp5.get(Textfield.class,"Remote IP").getText();
|
||||
int port = int(port_buffer);
|
||||
if(IP_buffer.compareTo("192.168.1.xxx")==0){
|
||||
println("connect error!");
|
||||
}
|
||||
else{
|
||||
myClient = new Client(this,IP_buffer,port);
|
||||
println("connect success!");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
myClient.stop();
|
||||
}
|
||||
void clearRecv(){
|
||||
cp5.get(Textarea.class,"recvData").clear();
|
||||
}
|
||||
void clearSend(){
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
void send_Textfield_SendData(){
|
||||
if(send_flag==1){
|
||||
myServer.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
else if(send_flag==2){
|
||||
myClient.write(cp5.get(Textfield.class,"sendData").getText());
|
||||
cp5.get(Textfield.class,"sendData").clear();
|
||||
}
|
||||
}
|
Binary file not shown.
@ -1,323 +0,0 @@
|
||||
# Picoweb web pico-framework for Pycopy, https://github.com/pfalcon/pycopy
|
||||
# Copyright (c) 2014-2020 Paul Sokolovsky
|
||||
# SPDX-License-Identifier: MIT
|
||||
import sys
|
||||
import gc
|
||||
import micropython
|
||||
import utime
|
||||
import uio
|
||||
import ure as re
|
||||
import uerrno
|
||||
import uasyncio as asyncio
|
||||
import pkg_resources
|
||||
|
||||
from .utils import parse_qs
|
||||
|
||||
SEND_BUFSZ = 128
|
||||
|
||||
|
||||
def get_mime_type(fname):
|
||||
# Provide minimal detection of important file
|
||||
# types to keep browsers happy
|
||||
if fname.endswith(".html"):
|
||||
return "text/html"
|
||||
if fname.endswith(".css"):
|
||||
return "text/css"
|
||||
if fname.endswith(".png") or fname.endswith(".jpg"):
|
||||
return "image"
|
||||
return "text/plain"
|
||||
|
||||
def sendstream(writer, f):
|
||||
buf = bytearray(SEND_BUFSZ)
|
||||
while True:
|
||||
l = f.readinto(buf)
|
||||
if not l:
|
||||
break
|
||||
yield from writer.awrite(buf, 0, l)
|
||||
|
||||
|
||||
def jsonify(writer, dict):
|
||||
import ujson
|
||||
yield from start_response(writer, "application/json")
|
||||
yield from writer.awrite(ujson.dumps(dict))
|
||||
|
||||
def start_response(writer, content_type="text/html; charset=utf-8", status="200", headers=None):
|
||||
yield from writer.awrite("HTTP/1.0 %s NA\r\n" % status)
|
||||
yield from writer.awrite("Content-Type: ")
|
||||
yield from writer.awrite(content_type)
|
||||
if not headers:
|
||||
yield from writer.awrite("\r\n\r\n")
|
||||
return
|
||||
yield from writer.awrite("\r\n")
|
||||
if isinstance(headers, bytes) or isinstance(headers, str):
|
||||
yield from writer.awrite(headers)
|
||||
else:
|
||||
for k, v in headers.items():
|
||||
yield from writer.awrite(k)
|
||||
yield from writer.awrite(": ")
|
||||
yield from writer.awrite(v)
|
||||
yield from writer.awrite("\r\n")
|
||||
yield from writer.awrite("\r\n")
|
||||
|
||||
def http_error(writer, status):
|
||||
yield from start_response(writer, status=status)
|
||||
yield from writer.awrite(status)
|
||||
|
||||
|
||||
class HTTPRequest:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def read_form_data(self):
|
||||
size = int(self.headers[b"Content-Length"])
|
||||
data = yield from self.reader.readexactly(size)
|
||||
form = parse_qs(data.decode())
|
||||
self.form = form
|
||||
|
||||
def parse_qs(self):
|
||||
form = parse_qs(self.qs)
|
||||
self.form = form
|
||||
|
||||
|
||||
class WebApp:
|
||||
|
||||
def __init__(self, pkg, routes=None, serve_static=True):
|
||||
if routes:
|
||||
self.url_map = routes
|
||||
else:
|
||||
self.url_map = []
|
||||
if pkg and pkg != "__main__":
|
||||
self.pkg = pkg.split(".", 1)[0]
|
||||
else:
|
||||
self.pkg = None
|
||||
if serve_static:
|
||||
self.url_map.append((re.compile("^/(static/.+)"), self.handle_static))
|
||||
self.mounts = []
|
||||
self.inited = False
|
||||
# Instantiated lazily
|
||||
self.template_loader = None
|
||||
self.headers_mode = "parse"
|
||||
|
||||
def parse_headers(self, reader):
|
||||
headers = {}
|
||||
while True:
|
||||
l = yield from reader.readline()
|
||||
if l == b"\r\n":
|
||||
break
|
||||
k, v = l.split(b":", 1)
|
||||
headers[k] = v.strip()
|
||||
return headers
|
||||
|
||||
def _handle(self, reader, writer):
|
||||
if self.debug > 1:
|
||||
micropython.mem_info()
|
||||
|
||||
close = True
|
||||
req = None
|
||||
try:
|
||||
request_line = yield from reader.readline()
|
||||
if request_line == b"":
|
||||
if self.debug >= 0:
|
||||
self.log.error("%s: EOF on request start" % reader)
|
||||
yield from writer.aclose()
|
||||
return
|
||||
req = HTTPRequest()
|
||||
# TODO: bytes vs str
|
||||
request_line = request_line.decode()
|
||||
method, path, proto = request_line.split()
|
||||
if self.debug >= 0:
|
||||
self.log.info('%.3f %s %s "%s %s"' % (utime.time(), req, writer, method, path))
|
||||
path = path.split("?", 1)
|
||||
qs = ""
|
||||
if len(path) > 1:
|
||||
qs = path[1]
|
||||
path = path[0]
|
||||
|
||||
#print("================")
|
||||
#print(req, writer)
|
||||
#print(req, (method, path, qs, proto), req.headers)
|
||||
|
||||
# Find which mounted subapp (if any) should handle this request
|
||||
app = self
|
||||
while True:
|
||||
found = False
|
||||
for subapp in app.mounts:
|
||||
root = subapp.url
|
||||
#print(path, "vs", root)
|
||||
if path[:len(root)] == root:
|
||||
app = subapp
|
||||
found = True
|
||||
path = path[len(root):]
|
||||
if not path.startswith("/"):
|
||||
path = "/" + path
|
||||
break
|
||||
if not found:
|
||||
break
|
||||
|
||||
# We initialize apps on demand, when they really get requests
|
||||
if not app.inited:
|
||||
app.init()
|
||||
|
||||
# Find handler to serve this request in app's url_map
|
||||
found = False
|
||||
for e in app.url_map:
|
||||
pattern = e[0]
|
||||
handler = e[1]
|
||||
extra = {}
|
||||
if len(e) > 2:
|
||||
extra = e[2]
|
||||
|
||||
if path == pattern:
|
||||
found = True
|
||||
break
|
||||
elif not isinstance(pattern, str):
|
||||
# Anything which is non-string assumed to be a ducktype
|
||||
# pattern matcher, whose .match() method is called. (Note:
|
||||
# Django uses .search() instead, but .match() is more
|
||||
# efficient and we're not exactly compatible with Django
|
||||
# URL matching anyway.)
|
||||
m = pattern.match(path)
|
||||
if m:
|
||||
req.url_match = m
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
headers_mode = "skip"
|
||||
else:
|
||||
headers_mode = extra.get("headers", self.headers_mode)
|
||||
|
||||
if headers_mode == "skip":
|
||||
while True:
|
||||
l = yield from reader.readline()
|
||||
if l == b"\r\n":
|
||||
break
|
||||
elif headers_mode == "parse":
|
||||
req.headers = yield from self.parse_headers(reader)
|
||||
else:
|
||||
assert headers_mode == "leave"
|
||||
|
||||
if found:
|
||||
req.method = method
|
||||
req.path = path
|
||||
req.qs = qs
|
||||
req.reader = reader
|
||||
close = yield from handler(req, writer)
|
||||
else:
|
||||
yield from start_response(writer, status="404")
|
||||
yield from writer.awrite("404\r\n")
|
||||
#print(req, "After response write")
|
||||
except Exception as e:
|
||||
if self.debug >= 0:
|
||||
self.log.exc(e, "%.3f %s %s %r" % (utime.time(), req, writer, e))
|
||||
yield from self.handle_exc(req, writer, e)
|
||||
|
||||
if close is not False:
|
||||
yield from writer.aclose()
|
||||
if __debug__ and self.debug > 1:
|
||||
self.log.debug("%.3f %s Finished processing request", utime.time(), req)
|
||||
|
||||
def handle_exc(self, req, resp, e):
|
||||
# Can be overriden by subclasses. req may be not (fully) initialized.
|
||||
# resp may already have (partial) content written.
|
||||
# NOTE: It's your responsibility to not throw exceptions out of
|
||||
# handle_exc(). If exception is thrown, it will be propagated, and
|
||||
# your webapp will terminate.
|
||||
# This method is a coroutine.
|
||||
return
|
||||
yield
|
||||
|
||||
def mount(self, url, app):
|
||||
"Mount a sub-app at the url of current app."
|
||||
# Inspired by Bottle. It might seem that dispatching to
|
||||
# subapps would rather be handled by normal routes, but
|
||||
# arguably, that's less efficient. Taking into account
|
||||
# that paradigmatically there's difference between handing
|
||||
# an action and delegating responisibilities to another
|
||||
# app, Bottle's way was followed.
|
||||
app.url = url
|
||||
self.mounts.append(app)
|
||||
# TODO: Consider instead to do better subapp prefix matching
|
||||
# in _handle() above.
|
||||
self.mounts.sort(key=lambda app: len(app.url), reverse=True)
|
||||
|
||||
def route(self, url, **kwargs):
|
||||
def _route(f):
|
||||
self.url_map.append((url, f, kwargs))
|
||||
return f
|
||||
return _route
|
||||
|
||||
def add_url_rule(self, url, func, **kwargs):
|
||||
# Note: this method skips Flask's "endpoint" argument,
|
||||
# because it's alleged bloat.
|
||||
self.url_map.append((url, func, kwargs))
|
||||
|
||||
def _load_template(self, tmpl_name):
|
||||
if self.template_loader is None:
|
||||
import utemplate.source
|
||||
self.template_loader = utemplate.source.Loader(self.pkg, "templates")
|
||||
return self.template_loader.load(tmpl_name)
|
||||
|
||||
def render_template(self, writer, tmpl_name, args=()):
|
||||
tmpl = self._load_template(tmpl_name)
|
||||
for s in tmpl(*args):
|
||||
yield from writer.awritestr(s)
|
||||
|
||||
def render_str(self, tmpl_name, args=()):
|
||||
#TODO: bloat
|
||||
tmpl = self._load_template(tmpl_name)
|
||||
return ''.join(tmpl(*args))
|
||||
|
||||
def sendfile(self, writer, fname, content_type=None, headers=None):
|
||||
if not content_type:
|
||||
content_type = get_mime_type(fname)
|
||||
try:
|
||||
with pkg_resources.resource_stream(self.pkg, fname) as f:
|
||||
yield from start_response(writer, content_type, "200", headers)
|
||||
yield from sendstream(writer, f)
|
||||
except OSError as e:
|
||||
if e.args[0] == uerrno.ENOENT:
|
||||
yield from http_error(writer, "404")
|
||||
else:
|
||||
raise
|
||||
|
||||
def handle_static(self, req, resp):
|
||||
path = req.url_match.group(1)
|
||||
print(path)
|
||||
if ".." in path:
|
||||
yield from http_error(resp, "403")
|
||||
return
|
||||
yield from self.sendfile(resp, path)
|
||||
|
||||
def init(self):
|
||||
"""Initialize a web application. This is for overriding by subclasses.
|
||||
This is good place to connect to/initialize a database, for example."""
|
||||
self.inited = True
|
||||
|
||||
def serve(self, loop, host, port):
|
||||
# Actually serve client connections. Subclasses may override this
|
||||
# to e.g. catch and handle exceptions when dealing with server socket
|
||||
# (which are otherwise unhandled and will terminate a Picoweb app).
|
||||
# Note: name and signature of this method may change.
|
||||
loop.create_task(asyncio.start_server(self._handle, host, port))
|
||||
loop.run_forever()
|
||||
|
||||
def run(self, host="127.0.0.1", port=8081, debug=False, lazy_init=False, log=None):
|
||||
if log is None and debug >= 0:
|
||||
import ulogging
|
||||
log = ulogging.getLogger("picoweb")
|
||||
if debug > 0:
|
||||
log.setLevel(ulogging.DEBUG)
|
||||
self.log = log
|
||||
gc.collect()
|
||||
self.debug = int(debug)
|
||||
self.init()
|
||||
if not lazy_init:
|
||||
for app in self.mounts:
|
||||
app.init()
|
||||
loop = asyncio.get_event_loop()
|
||||
if debug > 0:
|
||||
print("* Running on http://%s:%s/" % (host, port))
|
||||
self.serve(loop, host, port)
|
||||
loop.close()
|
@ -1,28 +0,0 @@
|
||||
def unquote_plus(s):
|
||||
# TODO: optimize
|
||||
s = s.replace("+", " ")
|
||||
arr = s.split("%")
|
||||
arr2 = [chr(int(x[:2], 16)) + x[2:] for x in arr[1:]]
|
||||
return arr[0] + "".join(arr2)
|
||||
|
||||
def parse_qs(s):
|
||||
res = {}
|
||||
if s:
|
||||
pairs = s.split("&")
|
||||
for p in pairs:
|
||||
vals = [unquote_plus(x) for x in p.split("=", 1)]
|
||||
if len(vals) == 1:
|
||||
vals.append(True)
|
||||
old = res.get(vals[0])
|
||||
if old is not None:
|
||||
if not isinstance(old, list):
|
||||
old = [old]
|
||||
res[vals[0]] = old
|
||||
old.append(vals[1])
|
||||
else:
|
||||
res[vals[0]] = vals[1]
|
||||
return res
|
||||
|
||||
#print(parse_qs("foo"))
|
||||
#print(parse_qs("fo%41o+bar=+++1"))
|
||||
#print(parse_qs("foo=1&foo=2"))
|
@ -1,27 +0,0 @@
|
||||
import uio
|
||||
|
||||
_c = {}
|
||||
|
||||
def resource_stream(package, resource):
|
||||
if package not in _c:
|
||||
try:
|
||||
if package:
|
||||
p = __import__(package + ".R", None, None, True)
|
||||
else:
|
||||
p = __import__("R")
|
||||
_c[package] = p.R
|
||||
except ImportError:
|
||||
if package:
|
||||
p = __import__(package)
|
||||
d = p.__path__
|
||||
else:
|
||||
d = "."
|
||||
# if d[0] != "/":
|
||||
# import uos
|
||||
# d = uos.getcwd() + "/" + d
|
||||
_c[package] = d + "/"
|
||||
|
||||
p = _c[package]
|
||||
if isinstance(p, dict):
|
||||
return uio.BytesIO(p[resource])
|
||||
return open(p + resource, "rb")
|
@ -1,94 +0,0 @@
|
||||
import sys
|
||||
|
||||
CRITICAL = 50
|
||||
ERROR = 40
|
||||
WARNING = 30
|
||||
INFO = 20
|
||||
DEBUG = 10
|
||||
NOTSET = 0
|
||||
|
||||
_level_dict = {
|
||||
CRITICAL: "CRIT",
|
||||
ERROR: "ERROR",
|
||||
WARNING: "WARN",
|
||||
INFO: "INFO",
|
||||
DEBUG: "DEBUG",
|
||||
}
|
||||
|
||||
_stream = sys.stderr
|
||||
|
||||
class Logger:
|
||||
|
||||
level = NOTSET
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def _level_str(self, level):
|
||||
l = _level_dict.get(level)
|
||||
if l is not None:
|
||||
return l
|
||||
return "LVL%s" % level
|
||||
|
||||
def setLevel(self, level):
|
||||
self.level = level
|
||||
|
||||
def isEnabledFor(self, level):
|
||||
return level >= (self.level or _level)
|
||||
|
||||
def log(self, level, msg, *args):
|
||||
if level >= (self.level or _level):
|
||||
_stream.write("%s:%s:" % (self._level_str(level), self.name))
|
||||
if not args:
|
||||
print(msg, file=_stream)
|
||||
else:
|
||||
print(msg % args, file=_stream)
|
||||
|
||||
def debug(self, msg, *args):
|
||||
self.log(DEBUG, msg, *args)
|
||||
|
||||
def info(self, msg, *args):
|
||||
self.log(INFO, msg, *args)
|
||||
|
||||
def warning(self, msg, *args):
|
||||
self.log(WARNING, msg, *args)
|
||||
|
||||
def error(self, msg, *args):
|
||||
self.log(ERROR, msg, *args)
|
||||
|
||||
def critical(self, msg, *args):
|
||||
self.log(CRITICAL, msg, *args)
|
||||
|
||||
def exc(self, e, msg, *args):
|
||||
self.log(ERROR, msg, *args)
|
||||
sys.print_exception(e, _stream)
|
||||
|
||||
def exception(self, msg, *args):
|
||||
self.exc(sys.exc_info()[1], msg, *args)
|
||||
|
||||
|
||||
_level = INFO
|
||||
_loggers = {}
|
||||
|
||||
def getLogger(name):
|
||||
if name in _loggers:
|
||||
return _loggers[name]
|
||||
l = Logger(name)
|
||||
_loggers[name] = l
|
||||
return l
|
||||
|
||||
def info(msg, *args):
|
||||
getLogger(None).info(msg, *args)
|
||||
|
||||
def debug(msg, *args):
|
||||
getLogger(None).debug(msg, *args)
|
||||
|
||||
def basicConfig(level=INFO, filename=None, stream=None, format=None):
|
||||
global _level, _stream
|
||||
_level = level
|
||||
if stream:
|
||||
_stream = stream
|
||||
if filename is not None:
|
||||
print("logging.basicConfig: filename arg is not supported")
|
||||
if format is not None:
|
||||
print("logging.basicConfig: format arg is not supported")
|
@ -1,119 +0,0 @@
|
||||
# This section uses firmware from Lemariva's Micropython-camera-driver.
|
||||
# for details, please refer to: https://github.com/lemariva/micropython-camera-driver
|
||||
import picoweb
|
||||
import utime
|
||||
import camera
|
||||
import gc
|
||||
|
||||
SSID = "********" # Enter your WiFi name
|
||||
PASSWORD = "********" # Enter your WiFi password
|
||||
|
||||
# Let ESP32 connect to wifi.
|
||||
def wifi_connect():
|
||||
import network
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to network...')
|
||||
wlan.connect(SSID, PASSWORD)
|
||||
start = utime.time()
|
||||
while not wlan.isconnected():
|
||||
utime.sleep(1)
|
||||
if utime.time()-start > 5:
|
||||
print("connect timeout!")
|
||||
break
|
||||
if wlan.isconnected():
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
# Initializing the Camera
|
||||
def camera_init():
|
||||
# Disable camera initialization
|
||||
camera.deinit()
|
||||
# Enable camera initialization
|
||||
camera.init(0, d0=4, d1=5, d2=18, d3=19, d4=36, d5=39, d6=34, d7=35,
|
||||
format=camera.JPEG, framesize=camera.FRAME_VGA,
|
||||
xclk_freq=camera.XCLK_20MHz,
|
||||
href=23, vsync=25, reset=-1, pwdn=-1,
|
||||
sioc=27, siod=26, xclk=21, pclk=22, fb_location=camera.PSRAM)
|
||||
|
||||
camera.framesize(camera.FRAME_VGA) # Set the camera resolution
|
||||
# The options are the following:
|
||||
# FRAME_96X96 FRAME_QQVGA FRAME_QCIF FRAME_HQVGA FRAME_240X240
|
||||
# FRAME_QVGA FRAME_CIF FRAME_HVGA FRAME_VGA FRAME_SVGA
|
||||
# FRAME_XGA FRAME_HD FRAME_SXGA FRAME_UXGA
|
||||
# Note: The higher the resolution, the more memory is used.
|
||||
# Note: And too much memory may cause the program to fail.
|
||||
|
||||
camera.flip(1) # Flip up and down window: 0-1
|
||||
camera.mirror(1) # Flip window left and right: 0-1
|
||||
camera.saturation(0) # saturation: -2,2 (default 0). -2 grayscale
|
||||
camera.brightness(0) # brightness: -2,2 (default 0). 2 brightness
|
||||
camera.contrast(0) # contrast: -2,2 (default 0). 2 highcontrast
|
||||
camera.quality(10) # quality: # 10-63 lower number means higher quality
|
||||
# Note: The smaller the number, the sharper the image. The larger the number, the more blurry the image
|
||||
|
||||
camera.speffect(camera.EFFECT_NONE) # special effects:
|
||||
# EFFECT_NONE (default) EFFECT_NEG EFFECT_BW EFFECT_RED EFFECT_GREEN EFFECT_BLUE EFFECT_RETRO
|
||||
camera.whitebalance(camera.WB_NONE) # white balance
|
||||
# WB_NONE (default) WB_SUNNY WB_CLOUDY WB_OFFICE WB_HOME
|
||||
|
||||
# HTTP Response Content
|
||||
index_web="""
|
||||
HTTP/1.0 200 OK\r\n
|
||||
<html>
|
||||
<head>
|
||||
<title>Video Streaming</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Video Streaming Demonstration</h1>
|
||||
<img src="/video" margin-top:100px; style="transform:rotate(180deg)"; />
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
# HTTP Response
|
||||
def index(req, resp):
|
||||
# You can construct an HTTP response completely yourself, having
|
||||
yield from resp.awrite(index_web)
|
||||
|
||||
# Send camera pictures
|
||||
def send_frame():
|
||||
buf = camera.capture()
|
||||
yield (b'--frame\r\n'
|
||||
b'Content-Type: image/jpeg\r\n\r\n'
|
||||
+ buf + b'\r\n')
|
||||
del buf
|
||||
gc.collect()
|
||||
|
||||
# Video transmission
|
||||
def video(req, resp):
|
||||
yield from picoweb.start_response(resp, content_type="multipart/x-mixed-replace; boundary=frame")
|
||||
while True:
|
||||
yield from resp.awrite(next(send_frame()))
|
||||
gc.collect()
|
||||
|
||||
|
||||
ROUTES = [
|
||||
# You can specify exact URI string matches...
|
||||
("/", index),
|
||||
("/video", video),
|
||||
]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
import ulogging as logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
camera_init()
|
||||
wifi_connect()
|
||||
|
||||
#Create an app object that contains two decorators
|
||||
app = picoweb.WebApp(__name__, ROUTES)
|
||||
|
||||
app.run(debug=1, port=80, host="0.0.0.0")
|
||||
# debug values:
|
||||
# -1 disable all logging
|
||||
# 0 (False) normal logging: requests and errors
|
||||
# 1 (True) debug logging
|
||||
# 2 extra debug logging
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,80 +0,0 @@
|
||||
from LCD_API import LcdApi
|
||||
from machine import I2C
|
||||
from time import sleep_ms
|
||||
|
||||
# The PCF8574 has a jumper selectable address: 0x20 - 0x27
|
||||
DEFAULT_I2C_ADDR = 0x27
|
||||
|
||||
# Defines shifts or masks for the various LCD line attached to the PCF8574
|
||||
|
||||
MASK_RS = 0x01
|
||||
MASK_RW = 0x02
|
||||
MASK_E = 0x04
|
||||
SHIFT_BACKLIGHT = 3
|
||||
SHIFT_DATA = 4
|
||||
|
||||
|
||||
class I2cLcd(LcdApi):
|
||||
def __init__(self, i2c, i2c_addr, num_lines, num_columns):
|
||||
self.i2c = i2c
|
||||
self.i2c_addr = i2c_addr
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([0]))
|
||||
sleep_ms(20) # Allow LCD time to powerup
|
||||
# Send reset 3 times
|
||||
self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
|
||||
sleep_ms(5) # need to delay at least 4.1 msec
|
||||
self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
|
||||
sleep_ms(1)
|
||||
self.hal_write_init_nibble(self.LCD_FUNCTION_RESET)
|
||||
sleep_ms(1)
|
||||
# Put LCD into 4 bit mode
|
||||
self.hal_write_init_nibble(self.LCD_FUNCTION)
|
||||
sleep_ms(1)
|
||||
LcdApi.__init__(self, num_lines, num_columns)
|
||||
cmd = self.LCD_FUNCTION
|
||||
if num_lines > 1:
|
||||
cmd |= self.LCD_FUNCTION_2LINES
|
||||
self.hal_write_command(cmd)
|
||||
|
||||
def hal_write_init_nibble(self, nibble):
|
||||
"""Writes an initialization nibble to the LCD.
|
||||
|
||||
This particular function is only used during initialization.
|
||||
"""
|
||||
byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E]))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
|
||||
|
||||
def hal_backlight_on(self):
|
||||
"""Allows the hal layer to turn the backlight on."""
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([1 << SHIFT_BACKLIGHT]))
|
||||
|
||||
def hal_backlight_off(self):
|
||||
"""Allows the hal layer to turn the backlight off."""
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([0]))
|
||||
|
||||
def hal_write_command(self, cmd):
|
||||
"""Writes a command to the LCD.
|
||||
|
||||
Data is latched on the falling edge of E.
|
||||
"""
|
||||
byte = ((self.backlight << SHIFT_BACKLIGHT) | (((cmd >> 4) & 0x0f) << SHIFT_DATA))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E]))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
|
||||
byte = ((self.backlight << SHIFT_BACKLIGHT) | ((cmd & 0x0f) << SHIFT_DATA))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E]))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
|
||||
if cmd <= 3:
|
||||
# The home and clear commands require a worst case delay of 4.1 msec
|
||||
sleep_ms(5)
|
||||
|
||||
def hal_write_data(self, data):
|
||||
"""Write data to the LCD."""
|
||||
byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | (((data >> 4) & 0x0f) << SHIFT_DATA))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E]))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
|
||||
byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | ((data & 0x0f) << SHIFT_DATA))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E]))
|
||||
self.i2c.writeto(self.i2c_addr, bytearray([byte]))
|
||||
|
||||
|
@ -1,190 +0,0 @@
|
||||
import time
|
||||
|
||||
class LcdApi:
|
||||
# The following constant names were lifted from the avrlib lcd.h
|
||||
# header file, however, I changed the definitions from bit numbers
|
||||
# to bit masks.
|
||||
#
|
||||
# LCD controller command set
|
||||
|
||||
LCD_CLR = 0x01 # DB0: clear display
|
||||
LCD_HOME = 0x02 # DB1: return to home position
|
||||
|
||||
LCD_ENTRY_MODE = 0x04 # DB2: set entry mode
|
||||
LCD_ENTRY_INC = 0x02 # --DB1: increment
|
||||
LCD_ENTRY_SHIFT = 0x01 # --DB0: shift
|
||||
|
||||
LCD_ON_CTRL = 0x08 # DB3: turn lcd/cursor on
|
||||
LCD_ON_DISPLAY = 0x04 # --DB2: turn display on
|
||||
LCD_ON_CURSOR = 0x02 # --DB1: turn cursor on
|
||||
LCD_ON_BLINK = 0x01 # --DB0: blinking cursor
|
||||
|
||||
LCD_MOVE = 0x10 # DB4: move cursor/display
|
||||
LCD_MOVE_DISP = 0x08 # --DB3: move display (0-> move cursor)
|
||||
LCD_MOVE_RIGHT = 0x04 # --DB2: move right (0-> left)
|
||||
|
||||
LCD_FUNCTION = 0x20 # DB5: function set
|
||||
LCD_FUNCTION_8BIT = 0x10 # --DB4: set 8BIT mode (0->4BIT mode)
|
||||
LCD_FUNCTION_2LINES = 0x08 # --DB3: two lines (0->one line)
|
||||
LCD_FUNCTION_10DOTS = 0x04 # --DB2: 5x10 font (0->5x7 font)
|
||||
LCD_FUNCTION_RESET = 0x30 # See "Initializing by Instruction" section
|
||||
|
||||
LCD_CGRAM = 0x40 # DB6: set CG RAM address
|
||||
LCD_DDRAM = 0x80 # DB7: set DD RAM address
|
||||
|
||||
LCD_RS_CMD = 0
|
||||
LCD_RS_DATA = 1
|
||||
|
||||
LCD_RW_WRITE = 0
|
||||
LCD_RW_READ = 1
|
||||
|
||||
def __init__(self, num_lines, num_columns):
|
||||
self.num_lines = num_lines
|
||||
if self.num_lines > 4:
|
||||
self.num_lines = 4
|
||||
self.num_columns = num_columns
|
||||
if self.num_columns > 40:
|
||||
self.num_columns = 40
|
||||
self.cursor_x = 0
|
||||
self.cursor_y = 0
|
||||
self.backlight = True
|
||||
self.display_off()
|
||||
self.backlight_on()
|
||||
self.clear()
|
||||
self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC)
|
||||
self.hide_cursor()
|
||||
self.display_on()
|
||||
|
||||
def clear(self):
|
||||
"""Clears the LCD display and moves the cursor to the top left
|
||||
corner.
|
||||
"""
|
||||
self.hal_write_command(self.LCD_CLR)
|
||||
self.hal_write_command(self.LCD_HOME)
|
||||
self.cursor_x = 0
|
||||
self.cursor_y = 0
|
||||
|
||||
def show_cursor(self):
|
||||
"""Causes the cursor to be made visible."""
|
||||
self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
|
||||
self.LCD_ON_CURSOR)
|
||||
|
||||
def hide_cursor(self):
|
||||
"""Causes the cursor to be hidden."""
|
||||
self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
|
||||
|
||||
def blink_cursor_on(self):
|
||||
"""Turns on the cursor, and makes it blink."""
|
||||
self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
|
||||
self.LCD_ON_CURSOR | self.LCD_ON_BLINK)
|
||||
|
||||
def blink_cursor_off(self):
|
||||
"""Turns on the cursor, and makes it no blink (i.e. be solid)."""
|
||||
self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY |
|
||||
self.LCD_ON_CURSOR)
|
||||
|
||||
def display_on(self):
|
||||
"""Turns on (i.e. unblanks) the LCD."""
|
||||
self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY)
|
||||
|
||||
def display_off(self):
|
||||
"""Turns off (i.e. blanks) the LCD."""
|
||||
self.hal_write_command(self.LCD_ON_CTRL)
|
||||
|
||||
def backlight_on(self):
|
||||
"""Turns the backlight on.
|
||||
|
||||
This isn't really an LCD command, but some modules have backlight
|
||||
controls, so this allows the hal to pass through the command.
|
||||
"""
|
||||
self.backlight = True
|
||||
self.hal_backlight_on()
|
||||
|
||||
def backlight_off(self):
|
||||
"""Turns the backlight off.
|
||||
|
||||
This isn't really an LCD command, but some modules have backlight
|
||||
controls, so this allows the hal to pass through the command.
|
||||
"""
|
||||
self.backlight = False
|
||||
self.hal_backlight_off()
|
||||
|
||||
def move_to(self, cursor_x, cursor_y):
|
||||
"""Moves the cursor position to the indicated position. The cursor
|
||||
position is zero based (i.e. cursor_x == 0 indicates first column).
|
||||
"""
|
||||
self.cursor_x = cursor_x
|
||||
self.cursor_y = cursor_y
|
||||
addr = cursor_x & 0x3f
|
||||
if cursor_y & 1:
|
||||
addr += 0x40 # Lines 1 & 3 add 0x40
|
||||
if cursor_y & 2:
|
||||
addr += 0x14 # Lines 2 & 3 add 0x14
|
||||
self.hal_write_command(self.LCD_DDRAM | addr)
|
||||
|
||||
def putchar(self, char):
|
||||
"""Writes the indicated character to the LCD at the current cursor
|
||||
position, and advances the cursor by one position.
|
||||
"""
|
||||
if char != '\n':
|
||||
self.hal_write_data(ord(char))
|
||||
self.cursor_x += 1
|
||||
if self.cursor_x >= self.num_columns or char == '\n':
|
||||
self.cursor_x = 0
|
||||
self.cursor_y += 1
|
||||
if self.cursor_y >= self.num_lines:
|
||||
self.cursor_y = 0
|
||||
self.move_to(self.cursor_x, self.cursor_y)
|
||||
|
||||
def putstr(self, string):
|
||||
"""Write the indicated string to the LCD at the current cursor
|
||||
position and advances the cursor position appropriately.
|
||||
"""
|
||||
for char in string:
|
||||
self.putchar(char)
|
||||
|
||||
def custom_char(self, location, charmap):
|
||||
"""Write a character to one of the 8 CGRAM locations, available
|
||||
as chr(0) through chr(7).
|
||||
"""
|
||||
location &= 0x7
|
||||
self.hal_write_command(self.LCD_CGRAM | (location << 3))
|
||||
self.hal_sleep_us(40)
|
||||
for i in range(8):
|
||||
self.hal_write_data(charmap[i])
|
||||
self.hal_sleep_us(40)
|
||||
self.move_to(self.cursor_x, self.cursor_y)
|
||||
|
||||
def hal_backlight_on(self):
|
||||
"""Allows the hal layer to turn the backlight on.
|
||||
|
||||
If desired, a derived HAL class will implement this function.
|
||||
"""
|
||||
pass
|
||||
|
||||
def hal_backlight_off(self):
|
||||
"""Allows the hal layer to turn the backlight off.
|
||||
|
||||
If desired, a derived HAL class will implement this function.
|
||||
"""
|
||||
pass
|
||||
|
||||
def hal_write_command(self, cmd):
|
||||
"""Write a command to the LCD.
|
||||
|
||||
It is expected that a derived HAL class will implement this
|
||||
function.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def hal_write_data(self, data):
|
||||
"""Write data to the LCD.
|
||||
|
||||
It is expected that a derived HAL class will implement this
|
||||
function.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def hal_sleep_us(self, usecs):
|
||||
"""Sleep for some time (given in microseconds)."""
|
||||
time.sleep_us(usecs)
|
@ -1,30 +0,0 @@
|
||||
from machine import ADC,Pin
|
||||
import time
|
||||
|
||||
adc0=ADC(Pin(36))
|
||||
adc1=ADC(Pin(39))
|
||||
adc2=ADC(Pin(34))
|
||||
adc3=ADC(Pin(35))
|
||||
adc4=ADC(Pin(32))
|
||||
adc5=ADC(Pin(33))
|
||||
adc0.atten(ADC.ATTN_11DB)
|
||||
adc1.atten(ADC.ATTN_11DB)
|
||||
adc2.atten(ADC.ATTN_11DB)
|
||||
adc3.atten(ADC.ATTN_11DB)
|
||||
adc4.atten(ADC.ATTN_11DB)
|
||||
adc5.atten(ADC.ATTN_11DB)
|
||||
adc0.width(ADC.WIDTH_12BIT)
|
||||
adc1.width(ADC.WIDTH_12BIT)
|
||||
adc2.width(ADC.WIDTH_12BIT)
|
||||
adc3.width(ADC.WIDTH_12BIT)
|
||||
adc4.width(ADC.WIDTH_12BIT)
|
||||
adc5.width(ADC.WIDTH_12BIT)
|
||||
|
||||
while True:
|
||||
print("adc0=",adc0.read())
|
||||
print("adc1=",adc1.read())
|
||||
print("adc2=",adc2.read())
|
||||
print("adc3=",adc3.read())
|
||||
print("adc4=",adc4.read())
|
||||
print("adc5=",adc5.read())
|
||||
time.sleep(0.1)
|
@ -1,32 +0,0 @@
|
||||
# DHT11/DHT22 driver for MicroPython on ESP8266
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
import esp
|
||||
|
||||
class DHTBase:
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
self.buf = bytearray(5)
|
||||
|
||||
def measure(self):
|
||||
buf = self.buf
|
||||
esp.dht_readinto(self.pin, buf)
|
||||
if (buf[0] + buf[1] + buf[2] + buf[3]) & 0xff != buf[4]:
|
||||
raise Exception("checksum error")
|
||||
|
||||
class DHT11(DHTBase):
|
||||
def humidity(self):
|
||||
return self.buf[0]
|
||||
|
||||
def temperature(self):
|
||||
return self.buf[2]
|
||||
|
||||
class DHT22(DHTBase):
|
||||
def humidity(self):
|
||||
return (self.buf[0] << 8 | self.buf[1]) * 0.1
|
||||
|
||||
def temperature(self):
|
||||
t = ((self.buf[2] & 0x7f) << 8 | self.buf[3]) * 0.1
|
||||
if self.buf[2] & 0x80:
|
||||
t = -t
|
||||
return t
|
@ -1,53 +0,0 @@
|
||||
from machine import Pin
|
||||
import time
|
||||
|
||||
soundVelocity=340
|
||||
distance=0
|
||||
|
||||
class SR04(object):
|
||||
def __init__(self, trig: int=13, echo: int=14):
|
||||
self._trigPin = Pin(trig,Pin.OUT,0)
|
||||
self._echoPin = Pin(echo,Pin.IN,0)
|
||||
|
||||
def distanceCM(self):
|
||||
self._trigPin.value(1)
|
||||
time.sleep_us(10)
|
||||
self._trigPin.value(0)
|
||||
while(self._echoPin.value()==0):
|
||||
pass
|
||||
pingStart=time.ticks_us()
|
||||
while(self._echoPin.value()==1):
|
||||
pass
|
||||
pingStop=time.ticks_us()
|
||||
pingTime=time.ticks_diff(pingStop,pingStart)
|
||||
distance=pingTime*soundVelocity//2//10000
|
||||
return distance
|
||||
|
||||
def distanceMM(self):
|
||||
self._trigPin.value(1)
|
||||
time.sleep_us(10)
|
||||
self._trigPin.value(0)
|
||||
while(self._echoPin.value()==0):
|
||||
pass
|
||||
pingStart=time.ticks_us()
|
||||
while(self._echoPin.value()==1):
|
||||
pass
|
||||
pingStop=time.ticks_us()
|
||||
pingTime=time.ticks_diff(pingStop,pingStart)
|
||||
distance=pingTime*soundVelocity//2//1000
|
||||
return distance
|
||||
|
||||
def distance(self):
|
||||
self._trigPin.value(1)
|
||||
time.sleep_us(10)
|
||||
self._trigPin.value(0)
|
||||
while(self._echoPin.value()==0):
|
||||
pass
|
||||
pingStart=time.ticks_us()
|
||||
while(self._echoPin.value()==1):
|
||||
pass
|
||||
pingStop=time.ticks_us()
|
||||
pingTime=time.ticks_diff(pingStop,pingStart)
|
||||
distance=pingTime*soundVelocity/2/10000
|
||||
return distance
|
||||
|
@ -1,52 +0,0 @@
|
||||
import machine
|
||||
import utime
|
||||
import micropython
|
||||
|
||||
class irGetCMD(object):
|
||||
def __init__(self, gpioNum):
|
||||
self.irRecv = machine.Pin(gpioNum, machine.Pin.IN, machine.Pin.PULL_UP)
|
||||
self.irRecv.irq(
|
||||
trigger=machine.Pin.IRQ_RISING | machine.Pin.IRQ_FALLING,
|
||||
handler=self.__logHandler)
|
||||
self.logList = []
|
||||
self.index = 0
|
||||
self.start = 0
|
||||
self.dictKeyNum = 0
|
||||
self.irDict = {}
|
||||
|
||||
def __logHandler(self, source):
|
||||
thisComeInTime = utime.ticks_us()
|
||||
if self.start == 0:
|
||||
self.start = thisComeInTime
|
||||
self.index = 0
|
||||
return
|
||||
self.logList.append(utime.ticks_diff(thisComeInTime, self.start))
|
||||
self.start = thisComeInTime
|
||||
self.index += 1
|
||||
|
||||
def ir_read(self):
|
||||
utime.sleep_ms(200)
|
||||
if utime.ticks_diff(
|
||||
utime.ticks_us(),
|
||||
self.start) > 800000 and self.index > 0:
|
||||
ir_buffer=[]
|
||||
for i in range(3,66,2):
|
||||
if self.logList[i]>800:
|
||||
ir_buffer.append(1)
|
||||
else:
|
||||
ir_buffer.append(0)
|
||||
irValue=0x00000000
|
||||
for i in range(0,4):
|
||||
for j in range(0,8):
|
||||
if ir_buffer[i*8+j]==1:
|
||||
irValue=irValue<<1
|
||||
irValue |= 0x01
|
||||
else:
|
||||
irValue=irValue<<1
|
||||
irValue &= 0xfffffffe
|
||||
# reset
|
||||
self.logList = []
|
||||
self.index = 0
|
||||
self.start = 0
|
||||
return hex(irValue)
|
||||
|
@ -1,124 +0,0 @@
|
||||
from machine import Pin
|
||||
import time
|
||||
|
||||
lastChangeTime=0
|
||||
keyState=0
|
||||
State=0
|
||||
|
||||
class KeyPad(object):
|
||||
def __init__(self, row1: int=14, row2: int=27, row3: int=26, row4: int=25, col1: int=13, col2: int=21, col3: int=22, col4: int=23):
|
||||
self._row1=Pin(row1,Pin.OUT)
|
||||
self._row2=Pin(row2,Pin.OUT)
|
||||
self._row3=Pin(row3,Pin.OUT)
|
||||
self._row4=Pin(row4,Pin.OUT)
|
||||
self._col1=Pin(col1,Pin.IN,Pin.PULL_DOWN)
|
||||
self._col2=Pin(col2,Pin.IN,Pin.PULL_DOWN)
|
||||
self._col3=Pin(col3,Pin.IN,Pin.PULL_DOWN)
|
||||
self._col4=Pin(col4,Pin.IN,Pin.PULL_DOWN)
|
||||
|
||||
|
||||
def scan(self):
|
||||
global lastChangeTime
|
||||
nowTime=time.ticks_ms()
|
||||
if(nowTime-lastChangeTime>10):
|
||||
lastChangeTime=nowTime
|
||||
if(self._readCol()!=0):
|
||||
State=self._readCol()
|
||||
return State
|
||||
|
||||
def _readRow1(self):
|
||||
self._setRow(1)
|
||||
if(self._col1.value()==1):
|
||||
keyState='1'
|
||||
elif(self._col2.value()==1):
|
||||
keyState='2'
|
||||
elif(self._col3.value()==1):
|
||||
keyState='3'
|
||||
elif(self._col4.value()==1):
|
||||
keyState='A'
|
||||
else:
|
||||
keyState=0
|
||||
return keyState
|
||||
|
||||
def _readRow2(self):
|
||||
self._setRow(2)
|
||||
if(self._col1.value()==1):
|
||||
keyState='4'
|
||||
elif(self._col2.value()==1):
|
||||
keyState='5'
|
||||
elif(self._col3.value()==1):
|
||||
keyState='6'
|
||||
elif(self._col4.value()==1):
|
||||
keyState='B'
|
||||
else:
|
||||
keyState=0
|
||||
return keyState
|
||||
|
||||
def _readRow3(self):
|
||||
self._setRow(3)
|
||||
if(self._col1.value()==1):
|
||||
keyState='7'
|
||||
elif(self._col2.value()==1):
|
||||
keyState='8'
|
||||
elif(self._col3.value()==1):
|
||||
keyState='9'
|
||||
elif(self._col4.value()==1):
|
||||
keyState='C'
|
||||
else:
|
||||
keyState=0
|
||||
return keyState
|
||||
|
||||
def _readRow4(self):
|
||||
self._setRow(4)
|
||||
if(self._col1.value()==1):
|
||||
keyState='*'
|
||||
elif(self._col2.value()==1):
|
||||
keyState='0'
|
||||
elif(self._col3.value()==1):
|
||||
keyState='#'
|
||||
elif(self._col4.value()==1):
|
||||
keyState='D'
|
||||
else:
|
||||
keyState=0
|
||||
return keyState
|
||||
|
||||
def _readCol(self):
|
||||
data_buffer1=self._readRow1()
|
||||
data_buffer2=self._readRow2()
|
||||
data_buffer3=self._readRow3()
|
||||
data_buffer4=self._readRow4()
|
||||
if (data_buffer1!=0):
|
||||
return data_buffer1
|
||||
elif (data_buffer2!=0):
|
||||
return data_buffer2
|
||||
elif (data_buffer3!=0):
|
||||
return data_buffer3
|
||||
elif (data_buffer4!=0):
|
||||
return data_buffer4
|
||||
|
||||
def _setRow(self,num):
|
||||
if num==1:
|
||||
self._row1.on()
|
||||
self._row2.off()
|
||||
self._row3.off()
|
||||
self._row4.off()
|
||||
if num==2:
|
||||
self._row1.off()
|
||||
self._row2.on()
|
||||
self._row3.off()
|
||||
self._row4.off()
|
||||
if num==3:
|
||||
self._row1.off()
|
||||
self._row2.off()
|
||||
self._row3.on()
|
||||
self._row4.off()
|
||||
if num==4:
|
||||
self._row1.off()
|
||||
self._row2.off()
|
||||
self._row3.off()
|
||||
self._row4.on()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,160 +0,0 @@
|
||||
import machine
|
||||
from machine import I2C,Pin
|
||||
import time
|
||||
|
||||
MPU_ADDR = const(0X68)
|
||||
|
||||
MPU_DEVICE_ID_REG = 0x75
|
||||
MPU_PWR_MGMT1_REG = 0x6B
|
||||
MPU_PWR_MGMT2_REG = 0x6C
|
||||
MPU_SELF_TESTX_REG = 0x0D
|
||||
MPU_SELF_TESTY_REG = 0x0E
|
||||
MPU_SELF_TESTZ_REG = 0x0F
|
||||
MPU_SELF_TESTA_REG = 0x10
|
||||
MPU_SAMPLE_RATE_REG = 0x19
|
||||
MPU_CFG_REG = 0x1A
|
||||
MPU_GYRO_CFG_REG = 0x1B
|
||||
MPU_ACCEL_CFG_REG = 0x1C
|
||||
MPU_MOTION_DET_REG = 0x1F
|
||||
MPU_FIFO_EN_REG = 0x23
|
||||
MPU_I2CMST_CTRL_REG = 0x24
|
||||
MPU_I2CSLV0_ADDR_REG = 0x25
|
||||
MPU_I2CSLV0_REG = 0x26
|
||||
MPU_I2CSLV0_CTRL_REG = 0x27
|
||||
MPU_I2CSLV1_ADDR_REG = 0x28
|
||||
MPU_I2CSLV1_REG = 0x29
|
||||
MPU_I2CSLV1_CTRL_REG = 0x2A
|
||||
MPU_I2CSLV2_ADDR_REG = 0x2B
|
||||
MPU_I2CSLV2_REG = 0x2C
|
||||
MPU_I2CSLV2_CTRL_REG = 0x2D
|
||||
MPU_I2CSLV3_ADDR_REG = 0x2E
|
||||
MPU_I2CSLV3_REG = 0x2F
|
||||
MPU_I2CSLV3_CTRL_REG = 0x30
|
||||
MPU_I2CSLV4_ADDR_REG = 0x31
|
||||
MPU_I2CSLV4_REG = 0x32
|
||||
MPU_I2CSLV4_DO_REG = 0x33
|
||||
MPU_I2CSLV4_CTRL_REG = 0x34
|
||||
MPU_I2CSLV4_DI_REG = 0x35
|
||||
|
||||
MPU_I2CMST_STA_REG = 0x36
|
||||
MPU_INTBP_CFG_REG = 0x37
|
||||
MPU_INT_EN_REG = 0x38
|
||||
MPU_INT_STA_REG = 0x3A
|
||||
|
||||
MPU_ACCEL_XOUTH_REG = 0x3B
|
||||
MPU_ACCEL_XOUTL_REG = 0x3C
|
||||
MPU_ACCEL_YOUTH_REG = 0x3D
|
||||
MPU_ACCEL_YOUTL_REG = 0x3E
|
||||
MPU_ACCEL_ZOUTH_REG = 0x3F
|
||||
MPU_ACCEL_ZOUTL_REG = 0x40
|
||||
|
||||
MPU_TEMP_OUTH_REG = 0x41
|
||||
MPU_TEMP_OUTL_REG = 0x42
|
||||
|
||||
MPU_GYRO_XOUTH_REG = 0x43
|
||||
MPU_GYRO_XOUTL_REG = 0x44
|
||||
MPU_GYRO_YOUTH_REG = 0x45
|
||||
MPU_GYRO_YOUTL_REG = 0x46
|
||||
MPU_GYRO_ZOUTH_REG = 0x47
|
||||
MPU_GYRO_ZOUTL_REG = 0x48
|
||||
|
||||
MPU_I2CSLV0_DO_REG = 0x63
|
||||
MPU_I2CSLV1_DO_REG = 0x64
|
||||
MPU_I2CSLV2_DO_REG = 0x65
|
||||
MPU_I2CSLV3_DO_REG = 0x66
|
||||
|
||||
MPU_I2CMST_DELAY_REG = 0x67
|
||||
MPU_SIGPATH_RST_REG = 0x68
|
||||
MPU_MDETECT_CTRL_REG = 0x69
|
||||
MPU_USER_CTRL_REG = 0x6A
|
||||
MPU_PWR_MGMT1_REG = 0x6B
|
||||
MPU_PWR_MGMT2_REG = 0x6C
|
||||
MPU_FIFO_CNTH_REG = 0x72
|
||||
MPU_FIFO_CNTL_REG = 0x73
|
||||
MPU_FIFO_RW_REG = 0x74
|
||||
MPU_DEVICE_ID_REG = 0x75
|
||||
|
||||
MPU_ADDR_ADDR = 0x68
|
||||
|
||||
class MPU6050(object):
|
||||
def __init__(self,sclpin,sdapin):
|
||||
self.i2c=I2C(scl=Pin(sclpin),sda=Pin(sdapin),freq=100000)
|
||||
|
||||
def Write_Mpu6050_REG(self,reg,dat):
|
||||
buf=bytearray(1)
|
||||
buf[0]=dat
|
||||
self.i2c.writeto_mem(MPU_ADDR,reg,buf)
|
||||
def Read_Mpu6050_REG(self,reg):
|
||||
t = self.i2c.readfrom_mem(MPU_ADDR,reg,1)[0]
|
||||
return (t>>4)*10 + (t%16)
|
||||
def Read_Mpu6050_Len(self,reg,len,buffer):
|
||||
#buffer=bytearray(len)
|
||||
self.i2c.readfrom_mem_into(MPU_ADDR,reg,buffer)
|
||||
|
||||
#fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
|
||||
def MPU_Set_Gyro_Fsr(self,fsr):
|
||||
return self.Write_Mpu6050_REG(MPU_GYRO_CFG_REG,fsr<<3)
|
||||
#fsr:0,±2g;1,±4g;2,±8g;3,±16g
|
||||
def MPU_Set_Accel_Fsr(self,fsr):
|
||||
return self.Write_Mpu6050_REG(MPU_ACCEL_CFG_REG,fsr<<3)
|
||||
|
||||
def MPU_Set_LPF(self,lpf):
|
||||
if(lpf>=188):
|
||||
data=1
|
||||
elif(lpf>=98):
|
||||
data=2
|
||||
elif(lpf>=42):
|
||||
data=3
|
||||
elif(lpf>=20):
|
||||
data=4
|
||||
elif(lpf>=10):
|
||||
data=5
|
||||
else:
|
||||
data=6;
|
||||
self.Write_Mpu6050_REG(MPU_CFG_REG,data)
|
||||
#rate:4~1000(Hz)
|
||||
def MPU_Set_Rate(self,rate):
|
||||
if(rate>1000):
|
||||
rate=1000
|
||||
if(rate<4):
|
||||
rate=4;
|
||||
data=int(1000/rate-1)
|
||||
datas=self.Write_Mpu6050_REG(MPU_SAMPLE_RATE_REG,data)
|
||||
return self.MPU_Set_LPF(rate/2)
|
||||
def MPU_Init(self):
|
||||
self.Write_Mpu6050_REG(MPU_PWR_MGMT1_REG,0x80)
|
||||
time.sleep_ms(100)
|
||||
self.Write_Mpu6050_REG(MPU_PWR_MGMT1_REG,0x00)
|
||||
self.MPU_Set_Gyro_Fsr(3)
|
||||
self.MPU_Set_Accel_Fsr(0)
|
||||
self.MPU_Set_Rate(50)
|
||||
self.Write_Mpu6050_REG(MPU_INT_EN_REG,0x00)
|
||||
self.Write_Mpu6050_REG(MPU_USER_CTRL_REG,0x00)
|
||||
self.Write_Mpu6050_REG(MPU_FIFO_EN_REG,0x00)
|
||||
self.Write_Mpu6050_REG(MPU_INTBP_CFG_REG,0x80)
|
||||
res = self.Read_Mpu6050_REG(MPU_DEVICE_ID_REG)
|
||||
if(res == 68):
|
||||
self.Write_Mpu6050_REG(MPU_PWR_MGMT1_REG,0x01)
|
||||
self.Write_Mpu6050_REG(MPU_PWR_MGMT2_REG,0x00)
|
||||
self.MPU_Set_Rate(50)
|
||||
else:
|
||||
return 1
|
||||
return 0
|
||||
#Get raw data
|
||||
def MPU_Get_Gyroscope(self):
|
||||
buf = bytearray(6)
|
||||
res = self.Read_Mpu6050_Len(MPU_GYRO_XOUTH_REG,6,buf)
|
||||
gx=(buf[0]<<8)|buf[1]
|
||||
gy=(buf[2]<<8)|buf[3]
|
||||
gz=(buf[4]<<8)|buf[5]
|
||||
#print('MPU_Get_Gyroscope: ',gx,gy,gz)
|
||||
return gx,gy,gz
|
||||
def MPU_Get_Accelerometer(self):
|
||||
buf = bytearray(6)
|
||||
res = self.Read_Mpu6050_Len(MPU_ACCEL_XOUTH_REG,6,buf)
|
||||
ax=(buf[0]<<8)|buf[1]
|
||||
ay=(buf[2]<<8)|buf[3]
|
||||
az=(buf[4]<<8)|buf[5]
|
||||
#print('MPU_Get_Accelerometer: ',ax,ay,az)
|
||||
return ax,ay,az
|
||||
|
@ -1,66 +0,0 @@
|
||||
from machine import Pin
|
||||
|
||||
# 74HC595
|
||||
# 16: VCC
|
||||
# 15, 1~7: Q0~Q7
|
||||
# 14: DS
|
||||
# 13: OE
|
||||
# 12: STCP
|
||||
# 11: SHCP
|
||||
# 9: Q7S
|
||||
# 8: GND
|
||||
|
||||
class Chip74HC595(object):
|
||||
def __init__(self, ds: int=14, stcp: int=12, shcp: int=13, oe: int=5):
|
||||
self._ds = Pin(ds, Pin.OUT, value=0)
|
||||
self._shcp = Pin(shcp, Pin.OUT, value=0)
|
||||
self._stcp = Pin(stcp, Pin.OUT, value=0)
|
||||
self._oe = Pin(oe, Pin.OUT, value=0)
|
||||
self.enable()
|
||||
|
||||
def shiftOut(self,direction,data):
|
||||
self._shcp.on()
|
||||
self._stcp.on()
|
||||
if direction:
|
||||
for i in range(8):
|
||||
bit=data<<i
|
||||
bit=bit&0x80
|
||||
if bit==0x80:
|
||||
self._ds.on()
|
||||
else:
|
||||
self._ds.off()
|
||||
self._shift_bit()
|
||||
self._send_data()
|
||||
if not direction:
|
||||
for i in range(8):
|
||||
bit=data>>i
|
||||
bit=bit&0x01
|
||||
if bit==0x01:
|
||||
self._ds.on()
|
||||
else:
|
||||
self._ds.off()
|
||||
self._shift_bit()
|
||||
self._send_data()
|
||||
|
||||
def clear(self):
|
||||
for i in range(8):
|
||||
self._ds.off()
|
||||
self._shift_bit()
|
||||
self._send_data()
|
||||
self.enable()
|
||||
|
||||
def _shift_bit(self):
|
||||
self._shcp.off()
|
||||
self._shcp.on()
|
||||
|
||||
def _send_data(self):
|
||||
self._stcp.off()
|
||||
self._stcp.on()
|
||||
|
||||
def disable(self):
|
||||
self._oe.on()
|
||||
|
||||
def enable(self):
|
||||
self._oe.off()
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
|
||||
from machine import Pin,PWM
|
||||
|
||||
class myServo(object):
|
||||
def __init__(self, pin: int=15, hz: int=50):
|
||||
self._servo = PWM(Pin(pin),hz)
|
||||
|
||||
def myServoWriteDuty(self, duty):
|
||||
if duty <= 26:
|
||||
duty = 26
|
||||
if duty >= 128:
|
||||
duty = 128
|
||||
self._servo.duty(duty)
|
||||
|
||||
def myServoWriteAngle(self, pos):
|
||||
if pos <= 0:
|
||||
pos = 0
|
||||
if pos >= 180:
|
||||
pos = 180
|
||||
pos_buffer=(pos/180)*(128-26)
|
||||
self._servo.duty(int(pos_buffer)+26)
|
||||
|
||||
def myServoWriteTime(self, us):
|
||||
if us <= 500:
|
||||
us = 500
|
||||
if us >= 2500:
|
||||
us = 2500
|
||||
pos_buffer=(1024*us)/20000
|
||||
self._servo.duty(int(pos_buffer))
|
||||
|
||||
def deinit(self):
|
||||
self._servo.deinit()
|
@ -1,33 +0,0 @@
|
||||
# NeoPixel driver for MicroPython on ESP32
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
from esp import neopixel_write
|
||||
|
||||
|
||||
class NeoPixel:
|
||||
ORDER = (1, 0, 2, 3)
|
||||
|
||||
def __init__(self, pin, n, bpp=3, timing=0):
|
||||
self.pin = pin
|
||||
self.n = n
|
||||
self.bpp = bpp
|
||||
self.buf = bytearray(n * bpp)
|
||||
self.pin.init(pin.OUT)
|
||||
self.timing = timing
|
||||
|
||||
def __setitem__(self, index, val):
|
||||
offset = index * self.bpp
|
||||
for i in range(self.bpp):
|
||||
self.buf[offset + self.ORDER[i]] = val[i]
|
||||
|
||||
def __getitem__(self, index):
|
||||
offset = index * self.bpp
|
||||
return tuple(self.buf[offset + self.ORDER[i]]
|
||||
for i in range(self.bpp))
|
||||
|
||||
def fill(self, color):
|
||||
for i in range(self.n):
|
||||
self[i] = color
|
||||
|
||||
def write(self):
|
||||
neopixel_write(self.pin, self.buf, self.timing)
|
@ -1,40 +0,0 @@
|
||||
from machine import Pin,PWM
|
||||
|
||||
class myPWM():
|
||||
def __init__(self, pwm0: int=15, pwm1: int=2, pwm2: int=0, pwm3: int=4, pwm4: int=5, pwm5: int=18, pwm6: int=19, pwm7: int=21):
|
||||
self._pwm0=PWM(Pin(pwm0),10000)
|
||||
self._pwm1=PWM(Pin(pwm1),10000)
|
||||
self._pwm2=PWM(Pin(pwm2),10000)
|
||||
self._pwm3=PWM(Pin(pwm3),10000)
|
||||
self._pwm4=PWM(Pin(pwm4),10000)
|
||||
self._pwm5=PWM(Pin(pwm5),10000)
|
||||
self._pwm6=PWM(Pin(pwm6),10000)
|
||||
self._pwm7=PWM(Pin(pwm7),10000)
|
||||
|
||||
def ledcWrite(self,chn,value):
|
||||
if chn==0:
|
||||
self._pwm0.duty(value)
|
||||
elif chn==1:
|
||||
self._pwm1.duty(value)
|
||||
elif chn==2:
|
||||
self._pwm2.duty(value)
|
||||
elif chn==3:
|
||||
self._pwm3.duty(value)
|
||||
elif chn==4:
|
||||
self._pwm4.duty(value)
|
||||
elif chn==5:
|
||||
self._pwm5.duty(value)
|
||||
elif chn==6:
|
||||
self._pwm6.duty(value)
|
||||
elif chn==7:
|
||||
self._pwm7.duty(value)
|
||||
|
||||
def deinit(self):
|
||||
self._pwm0.deinit()
|
||||
self._pwm1.deinit()
|
||||
self._pwm2.deinit()
|
||||
self._pwm3.deinit()
|
||||
self._pwm4.deinit()
|
||||
self._pwm5.deinit()
|
||||
self._pwm6.deinit()
|
||||
self._pwm7.deinit()
|
@ -1,74 +0,0 @@
|
||||
from machine import Pin
|
||||
import time
|
||||
|
||||
phasecw = [0x08,0x04,0x02,0x01]
|
||||
phaseccw = [0x01,0x02,0x04,0x08]
|
||||
out=0x01
|
||||
|
||||
class mystepmotor(object):
|
||||
def __init__(self, A: int=14, B: int=27, C: int=26, D: int=25):
|
||||
self._A = Pin(A,Pin.OUT,0)
|
||||
self._B = Pin(B,Pin.OUT,0)
|
||||
self._C = Pin(C,Pin.OUT,0)
|
||||
self._D = Pin(D,Pin.OUT,0)
|
||||
|
||||
def _motorcontrol(self,data):
|
||||
if data == 0x08:
|
||||
self._A.on()
|
||||
self._B.off()
|
||||
self._C.off()
|
||||
self._D.off()
|
||||
if data == 0x04:
|
||||
self._A.off()
|
||||
self._B.on()
|
||||
self._C.off()
|
||||
self._D.off()
|
||||
if data == 0x02:
|
||||
self._A.off()
|
||||
self._B.off()
|
||||
self._C.on()
|
||||
self._D.off()
|
||||
if data == 0x01:
|
||||
self._A.off()
|
||||
self._B.off()
|
||||
self._C.off()
|
||||
self._D.on()
|
||||
if data == 0x00:
|
||||
self._A.off()
|
||||
self._B.off()
|
||||
self._C.off()
|
||||
self._D.off()
|
||||
|
||||
def moveOneStep(self,direction):
|
||||
global out
|
||||
if direction == 1:
|
||||
if out!=0x08:
|
||||
out=out<<1
|
||||
else:
|
||||
out=0x01
|
||||
else:
|
||||
if direction == 0:
|
||||
if out!=0x01:
|
||||
out=out>>1
|
||||
else:
|
||||
out=0x08
|
||||
self._motorcontrol(out)
|
||||
|
||||
def moveSteps(self,direction,steps,us):
|
||||
for i in range(steps):
|
||||
self.moveOneStep(direction)
|
||||
time.sleep_us(us)
|
||||
|
||||
def moveAround(self,direction,turns,us):
|
||||
for i in range(turns):
|
||||
self.moveSteps(direction,32*64,us)
|
||||
|
||||
def moveAngle(self,angles,us):
|
||||
self.moveSteps(direction,32*64//angles,us)
|
||||
|
||||
def stop(self):
|
||||
self._motorcontrol(0x00)
|
||||
|
||||
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
|
||||
MAC OS: https://github.com/thonny/thonny/releases/download/v3.2.7/thonny-3.2.7.pkg
|
||||
|
||||
Windows: https://github.com/thonny/thonny/releases/download/v3.2.7/thonny-3.2.7.exe
|
||||
|
||||
Linux: The latest version:
|
||||
Binary bundle for PC (Thonny+Python):
|
||||
bash <(wget -O - https://thonny.org/installer-for-linux)
|
||||
|
||||
With pip:
|
||||
pip3 install thonny
|
||||
|
||||
Distro packages (may not be the latest version):
|
||||
Debian, Rasbian, Ubuntu, Mint and others:
|
||||
sudo apt install thonny
|
||||
|
||||
Fedora:
|
||||
sudo dnf install thonny
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user