d2db1b6c9274bc788b119e48ed92122e6646d871
Board-dat/NWI/NWI1044-dat/NWI1044-dat.md
| ... | ... | @@ -1,6 +1,10 @@ |
| 1 | 1 | |
| 2 | 2 | # NWI1044-dat |
| 3 | 3 | |
| 4 | + |
|
| 5 | +- [[CH9102-dat]] - [[nodemcu-dat]] - [[NWI1044-dat]] |
|
| 6 | + |
|
| 7 | + |
|
| 4 | 8 | [NodeMCU Wifi DEV Board, LUA, ESP8266](https://www.electrodragon.com/product/nodemcu-lua-amica-r2-esp8266-wifi-board/) |
| 5 | 9 | |
| 6 | 10 | - [legacy wiki page](https://w.electrodragon.com/w/ESP8266_NodeMCU_Dev_Board#R2_Version_Flash_Note) |
Board-dat/SDR/SDR1117-dat/SDR1117-dat.md
| ... | ... | @@ -26,6 +26,8 @@ board map and jumpers |
| 26 | 26 | |
| 27 | 27 | - [[NWI1044-dat]] - [[nodemcu-dat]] - [[ESP8266-HDK-dat]] - [[ELRS-board-dat]] |
| 28 | 28 | |
| 29 | +- [[MP1584-dat]] |
|
| 30 | + |
|
| 29 | 31 | |
| 30 | 32 | | custom | func | left | right | func | custom | |
| 31 | 33 | | ------ | ----- | ---- | ----- | ------------------ | ------------ | |
Chip-cn-dat/WCH-dat/CH9102-dat/2026-06-15-20-35-21.png
| ... | ... | Binary files /dev/null and b/Chip-cn-dat/WCH-dat/CH9102-dat/2026-06-15-20-35-21.png differ |
Chip-cn-dat/WCH-dat/CH9102-dat/CH9102-dat.md
| ... | ... | @@ -1,6 +1,8 @@ |
| 1 | 1 | |
| 2 | 2 | # CH9102-dat |
| 3 | 3 | |
| 4 | +- [[CH9102-dat]] - [[nodemcu-dat]] - [[NWI1044-dat]] |
|
| 5 | + |
|
| 4 | 6 |  |
| 5 | 7 | |
| 6 | 8 | - [[CH9102DS1.pdf]] - datasheet |
| ... | ... | @@ -8,6 +10,14 @@ |
| 8 | 10 | - CH9102F QFN24 |
| 9 | 11 | - CH9102X QFN28 |
| 10 | 12 | |
| 13 | + |
|
| 14 | +## install correct driver |
|
| 15 | + |
|
| 16 | + |
|
| 17 | + |
|
| 18 | +- [[CH9102X-druver.zip]] |
|
| 19 | + |
|
| 20 | + |
|
| 11 | 21 | ## SCH |
| 12 | 22 | |
| 13 | 23 |  |
Chip-cn-dat/WCH-dat/CH9102-dat/CH9102X-druver.zip
| ... | ... | Binary files /dev/null and b/Chip-cn-dat/WCH-dat/CH9102-dat/CH9102X-druver.zip differ |
Tech-dat/tech-dat.md
| ... | ... | @@ -40,7 +40,7 @@ |
| 40 | 40 | |
| 41 | 41 | - [[chip-dat]] - [[TI-dat]] - [[analog-device-dat]] - [[silicon-labs-dat]] - [[onsemi-dat]] - [[maxlinear-dat]] - [[microchip-dat]] - [[nordic-dat]] - [[bosch-dat]] - [[rockchip-dat]] - [[ESP32-dat]] - [[ESP8266-dat]] - [[realtek-dat]] - [[infineon-dat]] - [[74xx-dat]] |
| 42 | 42 | |
| 43 | -- [[chip-cn-dat]] - [[fuman-dat]] - [[injoinic-dat]] - [[jieli-dat]] |
|
| 43 | +- [[chip-cn-dat]] - [[fuman-dat]] - [[injoinic-dat]] - [[jieli-dat]] - [[wch-dat]] |
|
| 44 | 44 | |
| 45 | 45 | |
| 46 | 46 |
board-3rd-dat/nodemcu-dat/nodemcu-dat.md
| ... | ... | @@ -10,6 +10,9 @@ |
| 10 | 10 | |
| 11 | 11 | - [[AMS1117-dat]] |
| 12 | 12 | |
| 13 | +- [[CH9102-dat]] - [[nodemcu-dat]] - [[NWI1044-dat]] |
|
| 14 | + |
|
| 15 | + |
|
| 13 | 16 | |
| 14 | 17 | ## SCH |
| 15 | 18 |
code-dat/RC-code-dat/ELRS-rover-8871-3.ino
| ... | ... | @@ -0,0 +1,132 @@ |
| 1 | +// Define pins for each RC channel |
|
| 2 | +int aileronPin = 14; // Channel 1 (Throttle) // D5 |
|
| 3 | +int elevatorPin = 12; // Channel 2 (Steering) // D6 |
|
| 4 | + |
|
| 5 | +const int MOTOR1_CTRL_PIN = 4; // GPIO4 (D2) |
|
| 6 | +const int MOTOR2_CTRL_PIN = 5; // GPIO5 (D1) |
|
| 7 | + |
|
| 8 | +long aileronControl; // Mapped value from aileron channel (0-100) |
|
| 9 | +long elevatorControl; // Mapped value from elevator channel (0-100) |
|
| 10 | + |
|
| 11 | +unsigned long rawAileronPWM = 0; |
|
| 12 | +unsigned long rawElevatorPWM = 0; |
|
| 13 | + |
|
| 14 | +const int PWM_MAX = 255; // ESP8266 PWM range is 0-255 for analogWrite |
|
| 15 | +const int PWM_STOP = PWM_MAX / 2; // Approx. 127, this is brake/neutral for DRV8871 single-pin |
|
| 16 | +const int PWM_MIN_MOVING = 10; // Minimum offset from PWM_STOP to ensure movement |
|
| 17 | + |
|
| 18 | +// Add these global variables for current speeds and ramp step |
|
| 19 | +int currentMotor1Speed = PWM_STOP; |
|
| 20 | +int currentMotor2Speed = PWM_STOP; |
|
| 21 | +const int RAMP_STEP = 5; // Adjust for desired smoothness. Smaller is smoother. |
|
| 22 | + |
|
| 23 | +long readAileronControlSignal() { |
|
| 24 | + rawAileronPWM = pulseIn(aileronPin, HIGH, 25000); |
|
| 25 | + if (rawAileronPWM == 0 || rawAileronPWM < 900 || rawAileronPWM > 2100) { |
|
| 26 | + return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 27 | + } |
|
| 28 | + // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 29 | + long constrainedPWM = constrain(rawAileronPWM, 1000, 2000); |
|
| 30 | + return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 31 | +} |
|
| 32 | + |
|
| 33 | +long readElevatorControlSignal() { |
|
| 34 | + rawElevatorPWM = pulseIn(elevatorPin, HIGH, 25000); |
|
| 35 | + if (rawElevatorPWM == 0 || rawElevatorPWM < 900 || rawElevatorPWM > 2100) { |
|
| 36 | + return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 37 | + } |
|
| 38 | + // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 39 | + long constrainedPWM = constrain(rawElevatorPWM, 1000, 2000); |
|
| 40 | + return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 41 | +} |
|
| 42 | + |
|
| 43 | +void setup() { |
|
| 44 | + pinMode(aileronPin, INPUT); |
|
| 45 | + pinMode(elevatorPin, INPUT); |
|
| 46 | + |
|
| 47 | + pinMode(MOTOR1_CTRL_PIN, OUTPUT); |
|
| 48 | + pinMode(MOTOR2_CTRL_PIN, OUTPUT); |
|
| 49 | + |
|
| 50 | + Serial.begin(9600); |
|
| 51 | + |
|
| 52 | + // Initialize motors to braked state using currentSpeed variables |
|
| 53 | + currentMotor1Speed = PWM_STOP; |
|
| 54 | + currentMotor2Speed = PWM_STOP; |
|
| 55 | + analogWrite(MOTOR1_CTRL_PIN, currentMotor1Speed); |
|
| 56 | + analogWrite(MOTOR2_CTRL_PIN, currentMotor2Speed); |
|
| 57 | +} |
|
| 58 | + |
|
| 59 | +void loop() { |
|
| 60 | + // Read mapped control signals from each channel |
|
| 61 | + aileronControl = readAileronControlSignal(); // Throttle (0-100) |
|
| 62 | + elevatorControl = readElevatorControlSignal(); // Steering (0-100) |
|
| 63 | + |
|
| 64 | + String motor1TargetCommand = "BRAKE"; // Command based on stick input |
|
| 65 | + String motor2TargetCommand = "BRAKE"; |
|
| 66 | + int targetMotor1Speed = PWM_STOP; // Target speed for this loop iteration |
|
| 67 | + int targetMotor2Speed = PWM_STOP; // Target speed for this loop iteration |
|
| 68 | + |
|
| 69 | + // Handle throttle control (forward/reverse) |
|
| 70 | + if (aileronControl > 55) { |
|
| 71 | + // Forward |
|
| 72 | + int speed = map(aileronControl, 61, 100, PWM_STOP + PWM_MIN_MOVING, PWM_MAX); |
|
| 73 | + speed = constrain(speed, PWM_STOP + PWM_MIN_MOVING, PWM_MAX); |
|
| 74 | + targetMotor1Speed = speed; |
|
| 75 | + targetMotor2Speed = speed; |
|
| 76 | + motor1TargetCommand = "FORWARD"; |
|
| 77 | + motor2TargetCommand = "FORWARD"; |
|
| 78 | + } else if (aileronControl < 45) { |
|
| 79 | + // Reverse |
|
| 80 | + int speed = map(aileronControl, 39, 0, PWM_STOP - PWM_MIN_MOVING, 0); |
|
| 81 | + speed = constrain(speed, 0, PWM_STOP - PWM_MIN_MOVING); |
|
| 82 | + targetMotor1Speed = speed; |
|
| 83 | + targetMotor2Speed = speed; |
|
| 84 | + motor1TargetCommand = "REVERSE"; |
|
| 85 | + motor2TargetCommand = "REVERSE"; |
|
| 86 | + } else if (elevatorControl > 55) { |
|
| 87 | + // Turn right (throttle is neutral) |
|
| 88 | + int turnOffset = map(elevatorControl, 61, 100, PWM_MIN_MOVING, (PWM_MAX - PWM_STOP)); |
|
| 89 | + targetMotor1Speed = constrain(PWM_STOP + turnOffset, 0, PWM_MAX); |
|
| 90 | + targetMotor2Speed = constrain(PWM_STOP - turnOffset, 0, PWM_MAX); |
|
| 91 | + motor1TargetCommand = "TURN_R_M1"; |
|
| 92 | + motor2TargetCommand = "TURN_R_M2"; |
|
| 93 | + } else if (elevatorControl < 45) { |
|
| 94 | + // Turn left (throttle is neutral) |
|
| 95 | + int turnOffset = map(elevatorControl, 39, 0, PWM_MIN_MOVING, (PWM_MAX - PWM_STOP)); |
|
| 96 | + targetMotor1Speed = constrain(PWM_STOP - turnOffset, 0, PWM_MAX); |
|
| 97 | + targetMotor2Speed = constrain(PWM_STOP + turnOffset, 0, PWM_MAX); |
|
| 98 | + motor1TargetCommand = "TURN_L_M1"; |
|
| 99 | + motor2TargetCommand = "TURN_L_M2"; |
|
| 100 | + } else { |
|
| 101 | + // All sticks neutral - Target speeds remain PWM_STOP (Brake) |
|
| 102 | + // motor1TargetCommand and motor2TargetCommand remain "BRAKE" |
|
| 103 | + } |
|
| 104 | + |
|
| 105 | + // Ramping logic for Motor 1 |
|
| 106 | + if (currentMotor1Speed < targetMotor1Speed) { |
|
| 107 | + currentMotor1Speed = min(currentMotor1Speed + RAMP_STEP, targetMotor1Speed); |
|
| 108 | + } else if (currentMotor1Speed > targetMotor1Speed) { |
|
| 109 | + currentMotor1Speed = max(currentMotor1Speed - RAMP_STEP, targetMotor1Speed); |
|
| 110 | + } |
|
| 111 | + |
|
| 112 | + // Ramping logic for Motor 2 |
|
| 113 | + if (currentMotor2Speed < targetMotor2Speed) { |
|
| 114 | + currentMotor2Speed = min(currentMotor2Speed + RAMP_STEP, targetMotor2Speed); |
|
| 115 | + } else if (currentMotor2Speed > targetMotor2Speed) { |
|
| 116 | + currentMotor2Speed = max(currentMotor2Speed - RAMP_STEP, targetMotor2Speed); |
|
| 117 | + } |
|
| 118 | + |
|
| 119 | + // Apply the ramped speeds |
|
| 120 | + analogWrite(MOTOR1_CTRL_PIN, currentMotor1Speed); |
|
| 121 | + analogWrite(MOTOR2_CTRL_PIN, currentMotor2Speed); |
|
| 122 | + |
|
| 123 | + Serial.print("RC INPUT: "); |
|
| 124 | + Serial.print("Aileron="); Serial.print(rawAileronPWM); Serial.print("us ("); Serial.print(aileronControl); Serial.print("%), "); |
|
| 125 | + Serial.print("Elevator="); Serial.print(rawElevatorPWM); Serial.print("us ("); Serial.print(elevatorControl); Serial.print("%)"); |
|
| 126 | + Serial.print("MOTORS: "); |
|
| 127 | + Serial.print("M1_Cmd="); Serial.print(motor1TargetCommand); Serial.print(" (CurPWM:"); Serial.print(currentMotor1Speed); Serial.print(" TgtPWM:"); Serial.print(targetMotor1Speed); Serial.print("), "); |
|
| 128 | + Serial.print("M2_Cmd="); Serial.print(motor2TargetCommand); Serial.print(" (CurPWM:"); Serial.print(currentMotor2Speed); Serial.print(" TgtPWM:"); Serial.print(targetMotor2Speed); Serial.print(")"); |
|
| 129 | + |
|
| 130 | + Serial.println(); |
|
| 131 | + delay(20); // Delay for RC input reading cycle & ramping interval |
|
| 132 | +} |
|
| ... | ... | \ No newline at end of file |
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-rover-code-dat/motor-1-wifi-ap.ino
| ... | ... | @@ -1,120 +0,0 @@ |
| 1 | -#include <ESP8266WiFi.h> |
|
| 2 | -#include <ESP8266WebServer.h> |
|
| 3 | - |
|
| 4 | -// WiFi AP settings (fixed IP) |
|
| 5 | -const char* ssid = "MotorAP"; |
|
| 6 | -const char* password = "motorpass"; // set to "" for open AP |
|
| 7 | -IPAddress apIP(192, 168, 4, 1); |
|
| 8 | -IPAddress netMsk(255, 255, 255, 0); |
|
| 9 | - |
|
| 10 | -// Define pins for motor control |
|
| 11 | -const int ENA = 5; // PWM for speed for Motor (single motor) |
|
| 12 | -const int IN1 = 0; // Direction pin A for Motor (GPIO0) - be careful at boot |
|
| 13 | -const int IN2 = 2; // Direction pin B for Motor (GPIO2) |
|
| 14 | - |
|
| 15 | -int motorControl = 50; // 0..100, default mid-point |
|
| 16 | - |
|
| 17 | -ESP8266WebServer server(80); |
|
| 18 | - |
|
| 19 | -void applyMotorControl() { |
|
| 20 | - // Deadband: treat 40..60 as stop |
|
| 21 | - if (motorControl > 60) { |
|
| 22 | - // Forward: IN1 = HIGH, IN2 = LOW |
|
| 23 | - digitalWrite(IN1, HIGH); |
|
| 24 | - digitalWrite(IN2, LOW); |
|
| 25 | - |
|
| 26 | - // Map motorControl (61-100) to PWM speed (0-255) |
|
| 27 | - int motorSpeed = map(motorControl, 61, 100, 0, 255); |
|
| 28 | - motorSpeed = constrain(motorSpeed, 0, 255); |
|
| 29 | - analogWrite(ENA, motorSpeed); |
|
| 30 | - } else if (motorControl < 40) { |
|
| 31 | - // Reverse: IN1 = LOW, IN2 = HIGH |
|
| 32 | - digitalWrite(IN1, LOW); |
|
| 33 | - digitalWrite(IN2, HIGH); |
|
| 34 | - |
|
| 35 | - // Map motorControl (0-39) to PWM speed (0-255) |
|
| 36 | - int motorSpeed = map(motorControl, 0, 39, 0, 255); |
|
| 37 | - motorSpeed = constrain(motorSpeed, 0, 255); |
|
| 38 | - analogWrite(ENA, motorSpeed); |
|
| 39 | - } else { |
|
| 40 | - // Stop motor |
|
| 41 | - digitalWrite(IN1, LOW); |
|
| 42 | - digitalWrite(IN2, LOW); |
|
| 43 | - analogWrite(ENA, 0); |
|
| 44 | - } |
|
| 45 | -} |
|
| 46 | - |
|
| 47 | -String pageRoot() { |
|
| 48 | - String html = "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"; |
|
| 49 | - html += "<title>Motor AP Control</title></head><body>"; |
|
| 50 | - html += "<h2>Motor Control (0-100)</h2>"; |
|
| 51 | - html += "<input type=\"range\" id=\"s\" min=\"0\" max=\"100\" value=\"" + String(motorControl) + "\" oninput=\"update(this.value)\"/>"; |
|
| 52 | - html += "<span id=\"v\">" + String(motorControl) + "</span>"; |
|
| 53 | - html += "<script>function update(v){document.getElementById('v').innerText=v;fetch('/set?val='+v);}setInterval(function(){fetch('/status').then(r=>r.text()).then(t=>{document.getElementById('s').value=t;document.getElementById('v').innerText=t;});},1000);</script>"; |
|
| 54 | - html += "</body></html>"; |
|
| 55 | - return html; |
|
| 56 | -} |
|
| 57 | - |
|
| 58 | -void handleRoot() { |
|
| 59 | - server.send(200, "text/html", pageRoot()); |
|
| 60 | -} |
|
| 61 | - |
|
| 62 | -void handleSet() { |
|
| 63 | - if (!server.hasArg("val")) { |
|
| 64 | - server.send(400, "text/plain", "missing val"); |
|
| 65 | - return; |
|
| 66 | - } |
|
| 67 | - String v = server.arg("val"); |
|
| 68 | - int val = v.toInt(); |
|
| 69 | - val = constrain(val, 0, 100); |
|
| 70 | - motorControl = val; |
|
| 71 | - applyMotorControl(); |
|
| 72 | - server.send(200, "text/plain", String(motorControl)); |
|
| 73 | -} |
|
| 74 | - |
|
| 75 | -void handleStatus() { |
|
| 76 | - server.send(200, "text/plain", String(motorControl)); |
|
| 77 | -} |
|
| 78 | - |
|
| 79 | -void setup() { |
|
| 80 | - // Initialize pins |
|
| 81 | - pinMode(ENA, OUTPUT); |
|
| 82 | - pinMode(IN1, OUTPUT); |
|
| 83 | - pinMode(IN2, OUTPUT); |
|
| 84 | - |
|
| 85 | - // Initialize motor to off |
|
| 86 | - digitalWrite(IN1, LOW); |
|
| 87 | - digitalWrite(IN2, LOW); |
|
| 88 | - analogWrite(ENA, 0); |
|
| 89 | - |
|
| 90 | - Serial.begin(115200); |
|
| 91 | - delay(100); |
|
| 92 | - |
|
| 93 | - // Configure AP with fixed IP |
|
| 94 | - WiFi.softAPConfig(apIP, apIP, netMsk); |
|
| 95 | - WiFi.softAP(ssid, password); |
|
| 96 | - |
|
| 97 | - IPAddress myIP = WiFi.softAPIP(); |
|
| 98 | - Serial.print("AP IP address: "); |
|
| 99 | - Serial.println(myIP); |
|
| 100 | - |
|
| 101 | - // Configure server routes |
|
| 102 | - server.on("/", handleRoot); |
|
| 103 | - server.on("/set", handleSet); |
|
| 104 | - server.on("/status", handleStatus); |
|
| 105 | - server.begin(); |
|
| 106 | - Serial.println("HTTP server started"); |
|
| 107 | - |
|
| 108 | - // Ensure PWM range 0-255 |
|
| 109 | - analogWriteRange(255); |
|
| 110 | - |
|
| 111 | - // Apply initial motor state |
|
| 112 | - applyMotorControl(); |
|
| 113 | -} |
|
| 114 | - |
|
| 115 | -void loop() { |
|
| 116 | - server.handleClient(); |
|
| 117 | - // Optional: keep motor state applied in case other code modifies it |
|
| 118 | - // applyMotorControl(); |
|
| 119 | - delay(10); |
|
| 120 | -} |
|
| ... | ... | \ No newline at end of file |
code-dat/RC-code-dat/rover-8871-3.ino
| ... | ... | @@ -1,132 +0,0 @@ |
| 1 | -// Define pins for each RC channel |
|
| 2 | -int aileronPin = 14; // Channel 1 (Throttle) // D5 |
|
| 3 | -int elevatorPin = 12; // Channel 2 (Steering) // D6 |
|
| 4 | - |
|
| 5 | -const int MOTOR1_CTRL_PIN = 4; // GPIO4 (D2) |
|
| 6 | -const int MOTOR2_CTRL_PIN = 5; // GPIO5 (D1) |
|
| 7 | - |
|
| 8 | -long aileronControl; // Mapped value from aileron channel (0-100) |
|
| 9 | -long elevatorControl; // Mapped value from elevator channel (0-100) |
|
| 10 | - |
|
| 11 | -unsigned long rawAileronPWM = 0; |
|
| 12 | -unsigned long rawElevatorPWM = 0; |
|
| 13 | - |
|
| 14 | -const int PWM_MAX = 255; // ESP8266 PWM range is 0-255 for analogWrite |
|
| 15 | -const int PWM_STOP = PWM_MAX / 2; // Approx. 127, this is brake/neutral for DRV8871 single-pin |
|
| 16 | -const int PWM_MIN_MOVING = 10; // Minimum offset from PWM_STOP to ensure movement |
|
| 17 | - |
|
| 18 | -// Add these global variables for current speeds and ramp step |
|
| 19 | -int currentMotor1Speed = PWM_STOP; |
|
| 20 | -int currentMotor2Speed = PWM_STOP; |
|
| 21 | -const int RAMP_STEP = 5; // Adjust for desired smoothness. Smaller is smoother. |
|
| 22 | - |
|
| 23 | -long readAileronControlSignal() { |
|
| 24 | - rawAileronPWM = pulseIn(aileronPin, HIGH, 25000); |
|
| 25 | - if (rawAileronPWM == 0 || rawAileronPWM < 900 || rawAileronPWM > 2100) { |
|
| 26 | - return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 27 | - } |
|
| 28 | - // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 29 | - long constrainedPWM = constrain(rawAileronPWM, 1000, 2000); |
|
| 30 | - return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 31 | -} |
|
| 32 | - |
|
| 33 | -long readElevatorControlSignal() { |
|
| 34 | - rawElevatorPWM = pulseIn(elevatorPin, HIGH, 25000); |
|
| 35 | - if (rawElevatorPWM == 0 || rawElevatorPWM < 900 || rawElevatorPWM > 2100) { |
|
| 36 | - return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 37 | - } |
|
| 38 | - // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 39 | - long constrainedPWM = constrain(rawElevatorPWM, 1000, 2000); |
|
| 40 | - return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 41 | -} |
|
| 42 | - |
|
| 43 | -void setup() { |
|
| 44 | - pinMode(aileronPin, INPUT); |
|
| 45 | - pinMode(elevatorPin, INPUT); |
|
| 46 | - |
|
| 47 | - pinMode(MOTOR1_CTRL_PIN, OUTPUT); |
|
| 48 | - pinMode(MOTOR2_CTRL_PIN, OUTPUT); |
|
| 49 | - |
|
| 50 | - Serial.begin(9600); |
|
| 51 | - |
|
| 52 | - // Initialize motors to braked state using currentSpeed variables |
|
| 53 | - currentMotor1Speed = PWM_STOP; |
|
| 54 | - currentMotor2Speed = PWM_STOP; |
|
| 55 | - analogWrite(MOTOR1_CTRL_PIN, currentMotor1Speed); |
|
| 56 | - analogWrite(MOTOR2_CTRL_PIN, currentMotor2Speed); |
|
| 57 | -} |
|
| 58 | - |
|
| 59 | -void loop() { |
|
| 60 | - // Read mapped control signals from each channel |
|
| 61 | - aileronControl = readAileronControlSignal(); // Throttle (0-100) |
|
| 62 | - elevatorControl = readElevatorControlSignal(); // Steering (0-100) |
|
| 63 | - |
|
| 64 | - String motor1TargetCommand = "BRAKE"; // Command based on stick input |
|
| 65 | - String motor2TargetCommand = "BRAKE"; |
|
| 66 | - int targetMotor1Speed = PWM_STOP; // Target speed for this loop iteration |
|
| 67 | - int targetMotor2Speed = PWM_STOP; // Target speed for this loop iteration |
|
| 68 | - |
|
| 69 | - // Handle throttle control (forward/reverse) |
|
| 70 | - if (aileronControl > 55) { |
|
| 71 | - // Forward |
|
| 72 | - int speed = map(aileronControl, 61, 100, PWM_STOP + PWM_MIN_MOVING, PWM_MAX); |
|
| 73 | - speed = constrain(speed, PWM_STOP + PWM_MIN_MOVING, PWM_MAX); |
|
| 74 | - targetMotor1Speed = speed; |
|
| 75 | - targetMotor2Speed = speed; |
|
| 76 | - motor1TargetCommand = "FORWARD"; |
|
| 77 | - motor2TargetCommand = "FORWARD"; |
|
| 78 | - } else if (aileronControl < 45) { |
|
| 79 | - // Reverse |
|
| 80 | - int speed = map(aileronControl, 39, 0, PWM_STOP - PWM_MIN_MOVING, 0); |
|
| 81 | - speed = constrain(speed, 0, PWM_STOP - PWM_MIN_MOVING); |
|
| 82 | - targetMotor1Speed = speed; |
|
| 83 | - targetMotor2Speed = speed; |
|
| 84 | - motor1TargetCommand = "REVERSE"; |
|
| 85 | - motor2TargetCommand = "REVERSE"; |
|
| 86 | - } else if (elevatorControl > 55) { |
|
| 87 | - // Turn right (throttle is neutral) |
|
| 88 | - int turnOffset = map(elevatorControl, 61, 100, PWM_MIN_MOVING, (PWM_MAX - PWM_STOP)); |
|
| 89 | - targetMotor1Speed = constrain(PWM_STOP + turnOffset, 0, PWM_MAX); |
|
| 90 | - targetMotor2Speed = constrain(PWM_STOP - turnOffset, 0, PWM_MAX); |
|
| 91 | - motor1TargetCommand = "TURN_R_M1"; |
|
| 92 | - motor2TargetCommand = "TURN_R_M2"; |
|
| 93 | - } else if (elevatorControl < 45) { |
|
| 94 | - // Turn left (throttle is neutral) |
|
| 95 | - int turnOffset = map(elevatorControl, 39, 0, PWM_MIN_MOVING, (PWM_MAX - PWM_STOP)); |
|
| 96 | - targetMotor1Speed = constrain(PWM_STOP - turnOffset, 0, PWM_MAX); |
|
| 97 | - targetMotor2Speed = constrain(PWM_STOP + turnOffset, 0, PWM_MAX); |
|
| 98 | - motor1TargetCommand = "TURN_L_M1"; |
|
| 99 | - motor2TargetCommand = "TURN_L_M2"; |
|
| 100 | - } else { |
|
| 101 | - // All sticks neutral - Target speeds remain PWM_STOP (Brake) |
|
| 102 | - // motor1TargetCommand and motor2TargetCommand remain "BRAKE" |
|
| 103 | - } |
|
| 104 | - |
|
| 105 | - // Ramping logic for Motor 1 |
|
| 106 | - if (currentMotor1Speed < targetMotor1Speed) { |
|
| 107 | - currentMotor1Speed = min(currentMotor1Speed + RAMP_STEP, targetMotor1Speed); |
|
| 108 | - } else if (currentMotor1Speed > targetMotor1Speed) { |
|
| 109 | - currentMotor1Speed = max(currentMotor1Speed - RAMP_STEP, targetMotor1Speed); |
|
| 110 | - } |
|
| 111 | - |
|
| 112 | - // Ramping logic for Motor 2 |
|
| 113 | - if (currentMotor2Speed < targetMotor2Speed) { |
|
| 114 | - currentMotor2Speed = min(currentMotor2Speed + RAMP_STEP, targetMotor2Speed); |
|
| 115 | - } else if (currentMotor2Speed > targetMotor2Speed) { |
|
| 116 | - currentMotor2Speed = max(currentMotor2Speed - RAMP_STEP, targetMotor2Speed); |
|
| 117 | - } |
|
| 118 | - |
|
| 119 | - // Apply the ramped speeds |
|
| 120 | - analogWrite(MOTOR1_CTRL_PIN, currentMotor1Speed); |
|
| 121 | - analogWrite(MOTOR2_CTRL_PIN, currentMotor2Speed); |
|
| 122 | - |
|
| 123 | - Serial.print("RC INPUT: "); |
|
| 124 | - Serial.print("Aileron="); Serial.print(rawAileronPWM); Serial.print("us ("); Serial.print(aileronControl); Serial.print("%), "); |
|
| 125 | - Serial.print("Elevator="); Serial.print(rawElevatorPWM); Serial.print("us ("); Serial.print(elevatorControl); Serial.print("%)"); |
|
| 126 | - Serial.print("MOTORS: "); |
|
| 127 | - Serial.print("M1_Cmd="); Serial.print(motor1TargetCommand); Serial.print(" (CurPWM:"); Serial.print(currentMotor1Speed); Serial.print(" TgtPWM:"); Serial.print(targetMotor1Speed); Serial.print("), "); |
|
| 128 | - Serial.print("M2_Cmd="); Serial.print(motor2TargetCommand); Serial.print(" (CurPWM:"); Serial.print(currentMotor2Speed); Serial.print(" TgtPWM:"); Serial.print(targetMotor2Speed); Serial.print(")"); |
|
| 129 | - |
|
| 130 | - Serial.println(); |
|
| 131 | - delay(20); // Delay for RC input reading cycle & ramping interval |
|
| 132 | -} |
|
| ... | ... | \ No newline at end of file |
code-dat/projects/ESP8266-WIFI-motor-1.ino
| ... | ... | @@ -0,0 +1,149 @@ |
| 1 | +#include <ESP8266WiFi.h> |
|
| 2 | +#include <ESP8266WebServer.h> |
|
| 3 | + |
|
| 4 | +// WiFi AP settings (fixed IP) |
|
| 5 | +const char *ssid = "MotorAP"; |
|
| 6 | +const char *password = "motorpass"; // set to "" for open AP |
|
| 7 | +IPAddress apIP(192, 168, 4, 1); |
|
| 8 | +IPAddress netMsk(255, 255, 255, 0); |
|
| 9 | + |
|
| 10 | +// Define pins for motor control |
|
| 11 | +// Motor 1 |
|
| 12 | +const int M1_IN1 = 4; |
|
| 13 | +const int M1_IN2 = 5; |
|
| 14 | +// Motor 2 |
|
| 15 | +const int M2_IN1 = 0; |
|
| 16 | +const int M2_IN2 = 2; |
|
| 17 | + |
|
| 18 | +int motorControl = 50; // 0..100, default mid-point |
|
| 19 | + |
|
| 20 | +ESP8266WebServer server(80); |
|
| 21 | + |
|
| 22 | +void applyMotorControl() |
|
| 23 | +{ |
|
| 24 | + // Deadband: treat 40..60 as stop |
|
| 25 | + if (motorControl > 60) |
|
| 26 | + { |
|
| 27 | + // Forward |
|
| 28 | + int motorSpeed = map(motorControl, 61, 100, 0, 255); |
|
| 29 | + motorSpeed = constrain(motorSpeed, 0, 255); |
|
| 30 | + |
|
| 31 | + analogWrite(M1_IN1, motorSpeed); |
|
| 32 | + digitalWrite(M1_IN2, LOW); |
|
| 33 | + analogWrite(M2_IN1, motorSpeed); |
|
| 34 | + digitalWrite(M2_IN2, LOW); |
|
| 35 | + } |
|
| 36 | + else if (motorControl < 40) |
|
| 37 | + { |
|
| 38 | + // Reverse |
|
| 39 | + int motorSpeed = map(motorControl, 0, 39, 255, 0); |
|
| 40 | + motorSpeed = constrain(motorSpeed, 0, 255); |
|
| 41 | + |
|
| 42 | + digitalWrite(M1_IN1, LOW); |
|
| 43 | + analogWrite(M1_IN2, motorSpeed); |
|
| 44 | + digitalWrite(M2_IN1, LOW); |
|
| 45 | + analogWrite(M2_IN2, motorSpeed); |
|
| 46 | + } |
|
| 47 | + else |
|
| 48 | + { |
|
| 49 | + // Stop motors |
|
| 50 | + digitalWrite(M1_IN1, LOW); |
|
| 51 | + digitalWrite(M1_IN2, LOW); |
|
| 52 | + digitalWrite(M2_IN1, LOW); |
|
| 53 | + digitalWrite(M2_IN2, LOW); |
|
| 54 | + } |
|
| 55 | +} |
|
| 56 | + |
|
| 57 | +String pageRoot() |
|
| 58 | +{ |
|
| 59 | + String html = "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"; |
|
| 60 | + html += "<title>Motor AP Control</title></head><body>"; |
|
| 61 | + html += "<h2>Motor Control (0-100)</h2>"; |
|
| 62 | + html += "<input type=\"range\" id=\"s\" min=\"0\" max=\"100\" value=\"" + String(motorControl) + "\" oninput=\"update(this.value)\"/>"; |
|
| 63 | + html += "<span id=\"v\">" + String(motorControl) + "</span>"; |
|
| 64 | + html += "<script>function update(v){document.getElementById('v').innerText=v;fetch('/set?val='+v);}setInterval(function(){fetch('/status').then(r=>r.text()).then(t=>{document.getElementById('s').value=t;document.getElementById('v').innerText=t;});},1000);</script>"; |
|
| 65 | + html += "</body></html>"; |
|
| 66 | + return html; |
|
| 67 | +} |
|
| 68 | + |
|
| 69 | +void handleRoot() |
|
| 70 | +{ |
|
| 71 | + server.send(200, "text/html", pageRoot()); |
|
| 72 | +} |
|
| 73 | + |
|
| 74 | +void handleSet() |
|
| 75 | +{ |
|
| 76 | + if (!server.hasArg("val")) |
|
| 77 | + { |
|
| 78 | + server.send(400, "text/plain", "missing val"); |
|
| 79 | + return; |
|
| 80 | + } |
|
| 81 | + String v = server.arg("val"); |
|
| 82 | + int val = v.toInt(); |
|
| 83 | + val = constrain(val, 0, 100); |
|
| 84 | + motorControl = val; |
|
| 85 | + applyMotorControl(); |
|
| 86 | + server.send(200, "text/plain", String(motorControl)); |
|
| 87 | +} |
|
| 88 | + |
|
| 89 | +void handleStatus() |
|
| 90 | +{ |
|
| 91 | + server.send(200, "text/plain", String(motorControl)); |
|
| 92 | +} |
|
| 93 | + |
|
| 94 | +void setup() |
|
| 95 | +{ |
|
| 96 | + // Initialize pins |
|
| 97 | + pinMode(M1_IN1, OUTPUT); |
|
| 98 | + pinMode(M1_IN2, OUTPUT); |
|
| 99 | + pinMode(M2_IN1, OUTPUT); |
|
| 100 | + pinMode(M2_IN2, OUTPUT); |
|
| 101 | + |
|
| 102 | + // Initialize motors to off |
|
| 103 | + digitalWrite(M1_IN1, LOW); |
|
| 104 | + digitalWrite(M1_IN2, LOW); |
|
| 105 | + digitalWrite(M2_IN1, LOW); |
|
| 106 | + digitalWrite(M2_IN2, LOW); |
|
| 107 | + |
|
| 108 | + Serial.begin(115200); |
|
| 109 | + delay(100); |
|
| 110 | + |
|
| 111 | + Serial.println("Test..."); |
|
| 112 | + delay(1000); |
|
| 113 | + Serial.println("Test..."); |
|
| 114 | + delay(1000); |
|
| 115 | + Serial.println("Test..."); |
|
| 116 | + delay(1000); |
|
| 117 | + // Configure AP with fixed IP |
|
| 118 | + WiFi.softAPConfig(apIP, apIP, netMsk); |
|
| 119 | + WiFi.softAP(ssid, password); |
|
| 120 | + |
|
| 121 | + IPAddress myIP = WiFi.softAPIP(); |
|
| 122 | + Serial.print("AP IP address: "); |
|
| 123 | + Serial.println(myIP); |
|
| 124 | + |
|
| 125 | + // Configure server routes |
|
| 126 | + server.on("/", handleRoot); |
|
| 127 | + server.on("/set", handleSet); |
|
| 128 | + server.on("/status", handleStatus); |
|
| 129 | + server.begin(); |
|
| 130 | + Serial.println("HTTP server started"); |
|
| 131 | + |
|
| 132 | + // Ensure PWM range 0-255 |
|
| 133 | + analogWriteRange(255); |
|
| 134 | + |
|
| 135 | + // Apply initial motor state |
|
| 136 | + applyMotorControl(); |
|
| 137 | +} |
|
| 138 | + |
|
| 139 | +void loop() |
|
| 140 | +{ |
|
| 141 | + server.handleClient(); |
|
| 142 | + // Optional: keep motor state applied in case other code modifies it |
|
| 143 | + // applyMotorControl(); |
|
| 144 | + delay(10); |
|
| 145 | +} |
|
| 146 | + |
|
| 147 | + |
|
| 148 | + |
|
| 149 | + |