Network-dat/wifi-dat/WIFI-DAT.md
... ...
@@ -17,10 +17,12 @@
17 17
18 18
## cheatsheet
19 19
20
-- AP = access point
21
-- STA = station
20
+- AP = access point - Access point (ap) is the thing you connect to, e.g. wireless router.
21
+- STA = station - wireless/mobile station (sta) is your end user device, e.g. your phone.
22
+
23
+
24
+
22 25
23
-Access point (ap) is the thing you connect to, e.g. wireless router. wireless/mobile station (sta) is your end user device, e.g. your phone.
24 26
25 27
26 28
- [[espressif-dat]] - [[esp8266-dat]] - [[ESP32-dat]]
Tech-dat/acturator-dat/motor-driver-dat/motor-driver-code-dat/PWM-motor-esp-webserver-ap-1.ino
... ...
@@ -1,98 +0,0 @@
1
-#include <ESP8266WiFi.h>
2
-#include <ESP8266WebServer.h>
3
-
4
-// ===== WiFi 配置 =====
5
-const char* ssid = "YOUR_SSID";
6
-const char* password = "YOUR_PASSWORD";
7
-
8
-// ===== GPIO 定义 =====
9
-const int PWM_PIN = D1; // PWM 控制速度 IO5
10
-const int DIR_PIN1 = D2; // 方向引脚1 IO4
11
-const int DIR_PIN2 = D3; // 方向引脚2 IO0
12
-
13
-// ===== Web Server =====
14
-ESP8266WebServer server(80);
15
-
16
-// ===== HTML Web 控制界面 =====
17
-const char html_page[] PROGMEM = R"rawliteral(
18
-<!DOCTYPE html><html>
19
-<head><title>ESP8266 Motor Control</title></head>
20
-<body>
21
-<h2>Motor Control</h2>
22
-<form action="/control">
23
-Speed: <input type="range" name="speed" min="0" max="1023"><br>
24
-Direction:
25
-<select name="dir">
26
- <option value="fw">Forward</option>
27
- <option value="rv">Reverse</option>
28
-</select><br>
29
-<input type="submit" value="Apply">
30
-</form>
31
-</body></html>
32
-)rawliteral";
33
-
34
-// ===== 处理 Web 请求 =====
35
-void handleRoot() {
36
- server.send(200, "text/html", html_page);
37
-}
38
-
39
-void handleControl() {
40
- if (server.hasArg("speed")) {
41
- int speed = server.arg("speed").toInt(); // PWM 值 0-1023
42
- analogWrite(PWM_PIN, speed);
43
- }
44
-
45
- if (server.hasArg("dir")) {
46
- String d = server.arg("dir");
47
- if (d == "fw") {
48
- digitalWrite(DIR_PIN1, HIGH);
49
- digitalWrite(DIR_PIN2, LOW);
50
- } else {
51
- digitalWrite(DIR_PIN1, LOW);
52
- digitalWrite(DIR_PIN2, HIGH);
53
- }
54
- }
55
-
56
- server.sendHeader("Location", "/");
57
- server.send(302, "text/plain", "");
58
-}
59
-
60
-// ===== 初始化 =====
61
-void setup() {
62
- Serial.begin(115200);
63
-
64
- pinMode(PWM_PIN, OUTPUT);
65
- pinMode(DIR_PIN1, OUTPUT);
66
- pinMode(DIR_PIN2, OUTPUT);
67
-
68
- // 默认停止
69
- analogWrite(PWM_PIN, 0);
70
- digitalWrite(DIR_PIN1, LOW);
71
- digitalWrite(DIR_PIN2, LOW);
72
-
73
- // 启动为 WiFi AP 模式,使用固定 IP
74
- WiFi.mode(WIFI_AP);
75
- // 固定 AP 地址(根据需要修改)
76
- IPAddress apIP(192, 168, 50, 1);
77
- IPAddress apGateway(192, 168, 50, 1);
78
- IPAddress apSubnet(255, 255, 255, 0);
79
- if (!WiFi.softAPConfig(apIP, apGateway, apSubnet)) {
80
- Serial.println("softAPConfig failed");
81
- }
82
-
83
- // 启动软 AP:使用 ssid 和 password(注意:WPA2 密码至少 8 字符)
84
- WiFi.softAP(ssid, password);
85
- delay(500);
86
- Serial.println("");
87
- Serial.print("AP started, IP: ");
88
- Serial.println(WiFi.softAPIP());
89
-
90
- // Web 服务
91
- server.on("/", handleRoot);
92
- server.on("/control", handleControl);
93
- server.begin();
94
-}
95
-
96
-void loop() {
97
- server.handleClient();
98
-}
... ...
\ No newline at end of file
Tech-dat/acturator-dat/motor-driver-dat/motor-driver-code-dat/PWM-motor-esp-webserver-sta-1.ino.ino
... ...
@@ -1,94 +0,0 @@
1
-
2
-
3
-#include <ESP8266WiFi.h>
4
-#include <ESP8266WebServer.h>
5
-
6
-// ===== WiFi 配置 =====
7
-const char* ssid = "YOUR_SSID";
8
-const char* password = "YOUR_PASSWORD";
9
-
10
-// ===== GPIO 定义 =====
11
-const int PWM_PIN = D1; // PWM 控制速度 IO5
12
-const int DIR_PIN1 = D2; // 方向引脚1 IO4
13
-const int DIR_PIN2 = D3; // 方向引脚2 IO0
14
-
15
-// ===== Web Server =====
16
-ESP8266WebServer server(80);
17
-
18
-// ===== HTML Web 控制界面 =====
19
-const char html_page[] PROGMEM = R"rawliteral(
20
-<!DOCTYPE html><html>
21
-<head><title>ESP8266 Motor Control</title></head>
22
-<body>
23
-<h2>Motor Control</h2>
24
-<form action="/control">
25
-Speed: <input type="range" name="speed" min="0" max="1023"><br>
26
-Direction:
27
-<select name="dir">
28
- <option value="fw">Forward</option>
29
- <option value="rv">Reverse</option>
30
-</select><br>
31
-<input type="submit" value="Apply">
32
-</form>
33
-</body></html>
34
-)rawliteral";
35
-
36
-// ===== 处理 Web 请求 =====
37
-void handleRoot() {
38
- server.send(200, "text/html", html_page);
39
-}
40
-
41
-void handleControl() {
42
- if (server.hasArg("speed")) {
43
- int speed = server.arg("speed").toInt(); // PWM 值 0-1023
44
- analogWrite(PWM_PIN, speed);
45
- }
46
-
47
- if (server.hasArg("dir")) {
48
- String d = server.arg("dir");
49
- if (d == "fw") {
50
- digitalWrite(DIR_PIN1, HIGH);
51
- digitalWrite(DIR_PIN2, LOW);
52
- } else {
53
- digitalWrite(DIR_PIN1, LOW);
54
- digitalWrite(DIR_PIN2, HIGH);
55
- }
56
- }
57
-
58
- server.sendHeader("Location", "/");
59
- server.send(302, "text/plain", "");
60
-}
61
-
62
-// ===== 初始化 =====
63
-void setup() {
64
- Serial.begin(115200);
65
-
66
- pinMode(PWM_PIN, OUTPUT);
67
- pinMode(DIR_PIN1, OUTPUT);
68
- pinMode(DIR_PIN2, OUTPUT);
69
-
70
- // 默认停止
71
- analogWrite(PWM_PIN, 0);
72
- digitalWrite(DIR_PIN1, LOW);
73
- digitalWrite(DIR_PIN2, LOW);
74
-
75
- // 连接 WiFi
76
- WiFi.mode(WIFI_STA);
77
- WiFi.begin(ssid, password);
78
- while (WiFi.status() != WL_CONNECTED) {
79
- delay(500);
80
- Serial.print(".");
81
- }
82
- Serial.println("");
83
- Serial.print("Connected, IP: ");
84
- Serial.println(WiFi.localIP());
85
-
86
- // Web 服务
87
- server.on("/", handleRoot);
88
- server.on("/control", handleControl);
89
- server.begin();
90
-}
91
-
92
-void loop() {
93
- server.handleClient();
94
-}
... ...
\ No newline at end of file
Tech-dat/acturator-dat/motor-driver-dat/motor-driver-code-dat/motor-driver-code-dat.md
... ...
@@ -1,22 +0,0 @@
1
-
2
-# motor-driver-code-dat
3
-
4
-
5
-
6
-## drive by wifi and webserver
7
-
8
-- [[PWM-motor-esp-webserver-sta-1.ino]]
9
-
10
-- [[wifi-motor-control-dat]]
11
-
12
-- [[ESP32-rc-car-dat]]
13
-
14
-
15
-
16
-
17
-
18
-## ref
19
-
20
-- [[motor-driver-dat]]
21
-
22
-
code-dat/RC-code-dat/PWM-1ch.ino
... ...
@@ -1,74 +0,0 @@
1
-// Define pins for each RC channel
2
-int aileronPin = 2; // Channel 1
3
-
4
-const int ENA = 5; // PWM for speed for Motor 1
5
-const int ENB = 4; // PWM for speed for Motor 2
6
-
7
-const int IN1 = 0; // Direction for Motor 1 (IN2_Motor1 is inverted in hardware)
8
-const int IN2 = 2; // Direction pin 1 for Motor 2
9
-
10
-long aileronControl;
11
-
12
-long readAileronControlSignal() {
13
- unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
14
- if (rawPWM == 0) { // Timeout or no signal
15
- return 50; // Mid-point for 0-100 scale (1500us equivalent)
16
- }
17
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
18
- return map(constrainedPWM, 1000, 2000, 0, 100);
19
-}
20
-
21
-void setup() {
22
- pinMode(aileronPin, INPUT);
23
-
24
- pinMode(ENA, OUTPUT);
25
- pinMode(ENB, OUTPUT);
26
- pinMode(IN1, OUTPUT);
27
- pinMode(IN2, OUTPUT);
28
-
29
- // Initialize motors to off
30
- digitalWrite(IN1, LOW);
31
- digitalWrite(IN2, LOW);
32
- analogWrite(ENA, 0);
33
- analogWrite(ENB, 0);
34
-
35
- Serial.begin(9600);
36
-}
37
-
38
-void loop() {
39
- // Read mapped control signals from each channel
40
- aileronControl = readAileronControlSignal();
41
-
42
- // Print the mapped control signal values to the Serial Monitor
43
- Serial.print("Aileron: ");
44
- Serial.print(aileronControl);
45
- Serial.println(); // Newline for better readability
46
-
47
- if (aileronControl > 70) {
48
- // Forward
49
- digitalWrite(IN1, HIGH); // Motor 1 forward
50
- digitalWrite(IN2, HIGH); // Motor 2 forward
51
-
52
- // Map aileronControl (61-100) to PWM speed (e.g., 100-255)
53
- int motorSpeed = map(aileronControl, 61, 100, 100, 255);
54
- analogWrite(ENA, motorSpeed);
55
- analogWrite(ENB, motorSpeed);
56
- } else if (aileronControl < 30) {
57
- // Backward
58
- digitalWrite(IN1, LOW); // Motor 1 backward
59
- digitalWrite(IN2, LOW); // Motor 2 backward
60
-
61
- // Map aileronControl (0-39) to PWM speed (e.g., 255-100, reversing the range for backward)
62
- int motorSpeed = map(aileronControl, 0, 39, 255, 100);
63
- analogWrite(ENA, motorSpeed);
64
- analogWrite(ENB, motorSpeed);
65
- } else {
66
- // Stop motors (aileronControl is between 40 and 60 inclusive)
67
- digitalWrite(IN1, LOW);
68
- digitalWrite(IN2, LOW);
69
- analogWrite(ENA, 0);
70
- analogWrite(ENB, 0);
71
- }
72
-
73
- delay(100); // Limit output rate
74
-}
... ...
\ No newline at end of file
code-dat/RC-code-dat/PWM-2ch-2.ino
... ...
@@ -1,142 +0,0 @@
1
-// Define pins for each RC channel
2
-int aileronPin = 14; // Channel 1 (Throttle)
3
-int elevatorPin = 12; // Channel 2 (Steering)
4
-
5
-const int ENA = 5; // PWM for speed for Motor 1
6
-const int ENB = 4; // PWM for speed for Motor 2
7
-
8
-const int IN1 = 0; // Direction for Motor 1
9
-const int IN2 = 2; // Direction pin 1 for Motor 2
10
-
11
-long aileronControl; // Mapped value from aileron channel (0-100)
12
-long elevatorControl; // Mapped value from elevator channel (0-100)
13
-
14
-// Reads the PWM signal from the aileron channel and maps it to 0-100
15
-long readAileronControlSignal() {
16
- unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
17
- // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
18
- // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
19
- if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
20
- return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
21
- }
22
- // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
23
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
24
- return map(constrainedPWM, 1000, 2000, 0, 100);
25
-}
26
-
27
-// Reads the PWM signal from the elevator channel and maps it to 0-100
28
-long readElevatorControlSignal() {
29
- unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
30
- // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
31
- // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
32
- if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
33
- return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
34
- }
35
- // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
36
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
37
- return map(constrainedPWM, 1000, 2000, 0, 100);
38
-}
39
-
40
-void setup() {
41
- pinMode(aileronPin, INPUT);
42
- pinMode(elevatorPin, INPUT); // Initialize elevator pin
43
-
44
- pinMode(ENA, OUTPUT);
45
- pinMode(ENB, OUTPUT);
46
- pinMode(IN1, OUTPUT);
47
- pinMode(IN2, OUTPUT);
48
-
49
- // Initialize motors to off
50
- digitalWrite(IN1, LOW);
51
- digitalWrite(IN2, LOW);
52
- analogWrite(ENA, 0);
53
- analogWrite(ENB, 0);
54
-
55
- Serial.begin(9600);
56
-}
57
-
58
-// Helper function to control a single motor
59
-// pwmVal: -255 (full backward) to 255 (full forward)
60
-void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
61
- if (pwmVal > 0) { // Forward
62
- digitalWrite(dirPin, HIGH);
63
- analogWrite(speedPin, pwmVal);
64
- } else if (pwmVal < 0) { // Backward
65
- digitalWrite(dirPin, LOW);
66
- analogWrite(speedPin, -pwmVal); // Speed is positive
67
- } else { // Stop
68
- digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0
69
- analogWrite(speedPin, 0);
70
- }
71
-}
72
-
73
-// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255)
74
-// with a deadband around the center (e.g., 50).
75
-long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) {
76
- long mappedValue = 0;
77
- int deadbandLower = rcCenter - deadbandRadius;
78
- int deadbandUpper = rcCenter + deadbandRadius;
79
-
80
- if (rcValue < deadbandLower) {
81
- // Map the range [rcMin, deadbandLower - 1] to [outMin, -1]
82
- // Ensure deadbandLower - 1 is not less than rcMin
83
- if (deadbandLower -1 < rcMin) {
84
- mappedValue = outMin;
85
- } else {
86
- mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1);
87
- }
88
- } else if (rcValue > deadbandUpper) {
89
- // Map the range [deadbandUpper + 1, rcMax] to [1, outMax]
90
- // Ensure deadbandUpper + 1 is not greater than rcMax
91
- if (deadbandUpper + 1 > rcMax) {
92
- mappedValue = outMax;
93
- } else {
94
- mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax);
95
- }
96
- } else {
97
- // Inside deadband
98
- mappedValue = 0;
99
- }
100
- return constrain(mappedValue, outMin, outMax);
101
-}
102
-
103
-void loop() {
104
- // Read mapped control signals from each channel
105
- aileronControl = readAileronControlSignal(); // Throttle (0-100)
106
- elevatorControl = readElevatorControlSignal(); // Steering (0-100)
107
-
108
- // Print the mapped control signal values to the Serial Monitor
109
- Serial.print("Aileron (Throttle): ");
110
- Serial.print(aileronControl);
111
- Serial.print(" Elevator (Steering): ");
112
- Serial.print(elevatorControl);
113
- Serial.println();
114
-
115
- // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input)
116
- // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0.
117
- int deadbandRadius = 10;
118
- float steeringFactor = 3; // Adjust this value to change steering sensitivity
119
- float throttleFactor = 3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle)
120
-
121
- // Map control values with deadband
122
- long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255);
123
- long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255);
124
-
125
- // Apply sensitivity factors
126
- long throttleValue = rawThrottleValue * throttleFactor;
127
- long adjustedSteeringValue = rawSteeringValue * steeringFactor;
128
-
129
- // Mix throttle and steering for differential drive
130
- long motor1Pwm = throttleValue + adjustedSteeringValue;
131
- long motor2Pwm = throttleValue - adjustedSteeringValue;
132
-
133
- // Constrain PWM values to the valid range [-255, 255]
134
- motor1Pwm = constrain(motor1Pwm, -255, 255);
135
- motor2Pwm = constrain(motor2Pwm, -255, 255);
136
-
137
- // Set motor speeds and directions
138
- setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
139
- setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
140
-
141
- delay(20); // Shorter delay for better responsiveness
142
-}
... ...
\ No newline at end of file
code-dat/RC-code-dat/PWM-2ch-v2.ino
... ...
@@ -1,68 +0,0 @@
1
-// RC signal input pins
2
-#define THROTTLE_PIN 2 // Channel 1 (forward/back)
3
-#define STEERING_PIN 3 // Channel 2 (left/right)
4
-
5
-// Motor control pins (L298N)
6
-#define LEFT_ENA 9
7
-#define LEFT_IN1 4
8
-#define LEFT_IN2 5
9
-
10
-#define RIGHT_ENB 10
11
-#define RIGHT_IN3 6
12
-#define RIGHT_IN4 7
13
-
14
-int throttle, steering;
15
-
16
-void setup() {
17
- pinMode(THROTTLE_PIN, INPUT);
18
- pinMode(STEERING_PIN, INPUT);
19
-
20
- pinMode(LEFT_IN1, OUTPUT);
21
- pinMode(LEFT_IN2, OUTPUT);
22
- pinMode(LEFT_ENA, OUTPUT);
23
-
24
- pinMode(RIGHT_IN3, OUTPUT);
25
- pinMode(RIGHT_IN4, OUTPUT);
26
- pinMode(RIGHT_ENB, OUTPUT);
27
-
28
- Serial.begin(9600);
29
-}
30
-
31
-void loop() {
32
- // Read PWM input
33
- throttle = pulseIn(THROTTLE_PIN, HIGH, 25000);
34
- steering = pulseIn(STEERING_PIN, HIGH, 25000);
35
-
36
- // Center = 1500, range = 1000–2000
37
- int throttleVal = map(throttle, 1000, 2000, -255, 255);
38
- int steeringVal = map(steering, 1000, 2000, -100, 100); // less aggressive
39
-
40
- // Motor mixing (differential drive)
41
- int leftSpeed = constrain(throttleVal + steeringVal, -255, 255);
42
- int rightSpeed = constrain(throttleVal - steeringVal, -255, 255);
43
-
44
- setMotor(LEFT_IN1, LEFT_IN2, LEFT_ENA, leftSpeed);
45
- setMotor(RIGHT_IN3, RIGHT_IN4, RIGHT_ENB, rightSpeed);
46
-
47
- // Debug
48
- Serial.print("Throttle: "); Serial.print(throttleVal);
49
- Serial.print(" Steering: "); Serial.print(steeringVal);
50
- Serial.print(" L: "); Serial.print(leftSpeed);
51
- Serial.print(" R: "); Serial.println(rightSpeed);
52
-
53
- delay(20);
54
-}
55
-
56
-void setMotor(int in1, int in2, int ena, int speed) {
57
- if (speed > 0) {
58
- digitalWrite(in1, HIGH);
59
- digitalWrite(in2, LOW);
60
- } else if (speed < 0) {
61
- digitalWrite(in1, LOW);
62
- digitalWrite(in2, HIGH);
63
- } else {
64
- digitalWrite(in1, LOW);
65
- digitalWrite(in2, LOW);
66
- }
67
- analogWrite(ena, abs(speed));
68
-}
code-dat/RC-code-dat/RC-code-dat.md
... ...
@@ -2,6 +2,11 @@
2 2
# RC-code-dat
3 3
4 4
5
+
6
+
7
+
8
+
9
+
5 10
basic code == [[basic-code-1.ino]], or [[ultrasonic car-1602.pde]]
6 11
7 12
... ...
@@ -9,6 +14,10 @@ basic code == [[basic-code-1.ino]], or [[ultrasonic car-1602.pde]]
9 14
10 15
- [[SDR1064-dat]] - [[nodemcu-dat]]
11 16
17
+- [[serial-motor-1.ino]] - [[motor-1-wifi-ap.ino]]
18
+
19
+
20
+
12 21
## code
13 22
14 23
- [[PWM-1ch.ino]] - [[PWM-2ch.ino]] - [[PWM-2ch-v2.ino]]
code-dat/RC-code-dat/SDR1064-1.ino
... ...
@@ -1,94 +0,0 @@
1
-// Define pins for each RC channel
2
-int aileronPin = 14; // Channel 1 (Throttle)
3
-int elevatorPin = 12; // Channel 2 (Steering)
4
-
5
-const int ENA = 5; // PWM for speed for Motor 1
6
-const int ENB = 4; // PWM for speed for Motor 2
7
-
8
-const int IN1 = 0; // Direction for Motor 1
9
-const int IN2 = 2; // Direction pin 1 for Motor 2
10
-
11
-long aileronControl; // Mapped value from aileron channel (0-100)
12
-long elevatorControl; // Mapped value from elevator channel (0-100)
13
-
14
-// Reads the PWM signal from the aileron channel and maps it to 0-100
15
-long readAileronControlSignal() {
16
- unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
17
- // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
18
- if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
19
- return 50; // Mid-point for 0-100 scale
20
- }
21
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
22
- return map(constrainedPWM, 1000, 2000, 0, 100);
23
-}
24
-
25
-// Reads the PWM signal from the elevator channel and maps it to 0-100
26
-long readElevatorControlSignal() {
27
- unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
28
- // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
29
- if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
30
- return 50; // Mid-point for 0-100 scale
31
- }
32
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
33
- return map(constrainedPWM, 1000, 2000, 0, 100);
34
-}
35
-
36
-void setup() {
37
- pinMode(aileronPin, INPUT);
38
- pinMode(elevatorPin, INPUT);
39
-
40
- pinMode(ENA, OUTPUT);
41
- pinMode(ENB, OUTPUT);
42
- pinMode(IN1, OUTPUT);
43
- pinMode(IN2, OUTPUT);
44
-
45
- // Initialize motors to off
46
- digitalWrite(IN1, LOW);
47
- digitalWrite(IN2, LOW);
48
- analogWrite(ENA, 0);
49
- analogWrite(ENB, 0);
50
-}
51
-
52
-// Helper function to control a single motor
53
-// pwmVal: -255 (full backward) to 255 (full forward)
54
-void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
55
- if (pwmVal > 0) { // Forward
56
- digitalWrite(dirPin, HIGH);
57
- analogWrite(speedPin, pwmVal);
58
- } else if (pwmVal < 0) { // Backward
59
- digitalWrite(dirPin, LOW);
60
- analogWrite(speedPin, -pwmVal); // Speed is positive
61
- } else { // Stop
62
- digitalWrite(dirPin, LOW);
63
- analogWrite(speedPin, 0);
64
- }
65
-}
66
-
67
-void loop() {
68
- // Read mapped control signals from each channel
69
- aileronControl = readAileronControlSignal(); // Throttle (0-100, 50 is neutral)
70
- elevatorControl = readElevatorControlSignal(); // Steering (0-100, 50 is neutral)
71
-
72
- // Map control values directly
73
- // aileronControl (0-100) to throttleValue (-255 to 255)
74
- // 0 -> -255 (full reverse), 50 -> 0 (stop), 100 -> 255 (full forward)
75
- long throttleValue = map(aileronControl, 0, 100, -255, 255);
76
-
77
- // elevatorControl (0-100) to steeringValue (-255 to 255)
78
- // 0 -> -255 (full left turn effect), 50 -> 0 (straight), 100 -> 255 (full right turn effect)
79
- long steeringValue = map(elevatorControl, 0, 100, -255, 255);
80
-
81
- // Mix throttle and steering for differential drive
82
- long motor1Pwm = throttleValue + steeringValue;
83
- long motor2Pwm = throttleValue - steeringValue;
84
-
85
- // Constrain PWM values to the valid range [-255, 255]
86
- motor1Pwm = constrain(motor1Pwm, -255, 255);
87
- motor2Pwm = constrain(motor2Pwm, -255, 255);
88
-
89
- // Set motor speeds and directions
90
- setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
91
- setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
92
-
93
- delay(20); // Delay for responsiveness
94
-}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-2.ino
... ...
@@ -1,167 +0,0 @@
1
-#include <Adafruit_NeoPixel.h>
2
-
3
-// Define pins for each RC channel
4
-int aileronPin = 14; // Channel 1 (Throttle) // D5
5
-int elevatorPin = 12; // Channel 2 (Steering) // D6
6
-
7
-const int IN1 = 0; // Direction for Motor 1 // D3
8
-const int IN2 = 2; // Direction pin 1 for Motor 2 // D4
9
-
10
-// WS2812 LED Strip Configuration
11
-#define LED_PIN 15 // nodemcu pin D8
12
-#define LED_COUNT 8
13
-Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
14
-
15
-long aileronControl; // Mapped value from aileron channel (0-100)
16
-long elevatorControl; // Mapped value from elevator channel (0-100)
17
-
18
-// Reads the PWM signal from the aileron channel and maps it to 0-100
19
-long readAileronControlSignal() {
20
- unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
21
- // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
22
- // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
23
- if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
24
- return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
25
- }
26
- // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
27
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
28
- return map(constrainedPWM, 1000, 2000, 0, 100);
29
-}
30
-
31
-// Reads the PWM signal from the elevator channel and maps it to 0-100
32
-long readElevatorControlSignal() {
33
- unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
34
- // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
35
- // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
36
- if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
37
- return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
38
- }
39
- // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
40
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
41
- return map(constrainedPWM, 1000, 2000, 0, 100);
42
-}
43
-
44
-void setup() {
45
- pinMode(aileronPin, INPUT);
46
- pinMode(elevatorPin, INPUT); // Initialize elevator pin
47
-
48
- pinMode(ENA, OUTPUT);
49
- pinMode(ENB, OUTPUT);
50
- pinMode(IN1, OUTPUT);
51
- pinMode(IN2, OUTPUT);
52
-
53
- // Initialize motors to off
54
- digitalWrite(IN1, LOW);
55
- digitalWrite(IN2, LOW);
56
- analogWrite(ENA, 0);
57
- analogWrite(ENB, 0);
58
-
59
- Serial.begin(9600);
60
-
61
- strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
62
- strip.show(); // Turn OFF all pixels ASAP
63
- strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
64
-}
65
-
66
-// Helper function to control a single motor
67
-// pwmVal: -255 (full backward) to 255 (full forward)
68
-void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
69
- if (pwmVal > 0) { // Forward
70
- digitalWrite(dirPin, HIGH);
71
- analogWrite(speedPin, pwmVal);
72
- } else if (pwmVal < 0) { // Backward
73
- digitalWrite(dirPin, LOW);
74
- analogWrite(speedPin, -pwmVal); // Speed is positive
75
- } else { // Stop
76
- digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0
77
- analogWrite(speedPin, 0);
78
- }
79
-}
80
-
81
-// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255)
82
-// with a deadband around the center (e.g., 50).
83
-long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) {
84
- long mappedValue = 0;
85
- int deadbandLower = rcCenter - deadbandRadius;
86
- int deadbandUpper = rcCenter + deadbandRadius;
87
-
88
- if (rcValue < deadbandLower) {
89
- // Map the range [rcMin, deadbandLower - 1] to [outMin, -1]
90
- // Ensure deadbandLower - 1 is not less than rcMin
91
- if (deadbandLower -1 < rcMin) {
92
- mappedValue = outMin;
93
- } else {
94
- mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1);
95
- }
96
- } else if (rcValue > deadbandUpper) {
97
- // Map the range [deadbandUpper + 1, rcMax] to [1, outMax]
98
- // Ensure deadbandUpper + 1 is not greater than rcMax
99
- if (deadbandUpper + 1 > rcMax) {
100
- mappedValue = outMax;
101
- } else {
102
- mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax);
103
- }
104
- } else {
105
- // Inside deadband
106
- mappedValue = 0;
107
- }
108
- return constrain(mappedValue, outMin, outMax);
109
-}
110
-
111
-// Function to create a random blinking effect for WS2812 LEDs
112
-void randomBlinkEffect() {
113
- for (int i = 0; i < LED_COUNT; i++) {
114
- // Turn on a random LED with a random color
115
- if (random(0, 2) == 1) { // 50% chance to turn on this LED
116
- strip.setPixelColor(i, strip.Color(random(0, 256), random(0, 256), random(0, 256)));
117
- } else {
118
- strip.setPixelColor(i, strip.Color(0, 0, 0)); // Turn off
119
- }
120
- }
121
- strip.show(); // Send the updated pixel colors to the hardware.
122
- delay(100); // Wait a short period
123
-}
124
-
125
-void loop() {
126
- // Read mapped control signals from each channel
127
- aileronControl = readAileronControlSignal(); // Throttle (0-100)
128
- elevatorControl = readElevatorControlSignal(); // Steering (0-100)
129
-
130
- // Print the mapped control signal values to the Serial Monitor
131
- Serial.print("Aileron (Throttle): ");
132
- Serial.print(aileronControl);
133
- Serial.print(" Elevator (Steering): ");
134
- Serial.print(elevatorControl);
135
- Serial.println();
136
-
137
- // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input)
138
- // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0.
139
- int deadbandRadius = 15;
140
- float steeringFactor = 3; // Adjust this value to change steering sensitivity
141
- float throttleFactor = 3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle)
142
-
143
- // Map control values with deadband
144
- long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255);
145
- long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255);
146
-
147
- // Apply sensitivity factors
148
- long throttleValue = rawThrottleValue * throttleFactor;
149
- long adjustedSteeringValue = rawSteeringValue * steeringFactor;
150
-
151
- // Mix throttle and steering for differential drive
152
- long motor1Pwm = throttleValue + adjustedSteeringValue;
153
- long motor2Pwm = throttleValue - adjustedSteeringValue;
154
-
155
- // Constrain PWM values to the valid range [-255, 255]
156
- motor1Pwm = constrain(motor1Pwm, -255, 255);
157
- motor2Pwm = constrain(motor2Pwm, -255, 255);
158
-
159
- // Set motor speeds and directions
160
- setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
161
- setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
162
-
163
- // Add the LED effect
164
- randomBlinkEffect();
165
-
166
- delay(20); // Shorter delay for better responsiveness
167
-}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-3.ino
... ...
@@ -1,136 +0,0 @@
1
-// Define pins for each RC channel
2
-int aileronPin = 14; // Channel 1 (Throttle)
3
-int elevatorPin = 12; // Channel 2 (Steering)
4
-
5
-const int ENA = 5; // PWM for speed for Motor 1
6
-const int ENB = 4; // PWM for speed for Motor 2
7
-
8
-const int IN1 = 0; // Direction for Motor 1
9
-const int IN2 = 2; // Direction pin 1 for Motor 2
10
-
11
-long aileronControl; // Mapped value from aileron channel (0-100)
12
-long elevatorControl; // Mapped value from elevator channel (0-100)
13
-
14
-// Reads the PWM signal from the aileron channel and maps it to 0-100
15
-long readAileronControlSignal() {
16
- unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
17
- if (rawPWM == 0) { // Timeout or no signal
18
- return 50; // Mid-point for 0-100 scale (1500us equivalent)
19
- }
20
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
21
- return map(constrainedPWM, 1000, 2000, 0, 100);
22
-}
23
-
24
-// Reads the PWM signal from the elevator channel and maps it to 0-100
25
-long readElevatorControlSignal() {
26
- unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
27
- if (rawPWM == 0) { // Timeout or no signal
28
- return 50; // Mid-point for 0-100 scale (1500us equivalent)
29
- }
30
- long constrainedPWM = constrain(rawPWM, 1000, 2000);
31
- return map(constrainedPWM, 1000, 2000, 0, 100);
32
-}
33
-
34
-void setup() {
35
- pinMode(aileronPin, INPUT);
36
- pinMode(elevatorPin, INPUT); // Initialize elevator pin
37
-
38
- pinMode(ENA, OUTPUT);
39
- pinMode(ENB, OUTPUT);
40
- pinMode(IN1, OUTPUT);
41
- pinMode(IN2, OUTPUT);
42
-
43
- // Initialize motors to off
44
- digitalWrite(IN1, LOW);
45
- digitalWrite(IN2, LOW);
46
- analogWrite(ENA, 0);
47
- analogWrite(ENB, 0);
48
-
49
- Serial.begin(9600);
50
-}
51
-
52
-// Helper function to control a single motor
53
-// pwmVal: -255 (full backward) to 255 (full forward)
54
-void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
55
- if (pwmVal > 0) { // Forward
56
- digitalWrite(dirPin, HIGH);
57
- analogWrite(speedPin, pwmVal);
58
- } else if (pwmVal < 0) { // Backward
59
- digitalWrite(dirPin, LOW);
60
- analogWrite(speedPin, -pwmVal); // Speed is positive
61
- } else { // Stop
62
- digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0
63
- analogWrite(speedPin, 0);
64
- }
65
-}
66
-
67
-// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255)
68
-// with a deadband around the center (e.g., 50).
69
-long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) {
70
- long mappedValue = 0;
71
- int deadbandLower = rcCenter - deadbandRadius;
72
- int deadbandUpper = rcCenter + deadbandRadius;
73
-
74
- if (rcValue < deadbandLower) {
75
- // Map the range [rcMin, deadbandLower - 1] to [outMin, -1]
76
- // Ensure deadbandLower - 1 is not less than rcMin
77
- if (deadbandLower -1 < rcMin) {
78
- mappedValue = outMin;
79
- } else {
80
- mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1);
81
- }
82
- } else if (rcValue > deadbandUpper) {
83
- // Map the range [deadbandUpper + 1, rcMax] to [1, outMax]
84
- // Ensure deadbandUpper + 1 is not greater than rcMax
85
- if (deadbandUpper + 1 > rcMax) {
86
- mappedValue = outMax;
87
- } else {
88
- mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax);
89
- }
90
- } else {
91
- // Inside deadband
92
- mappedValue = 0;
93
- }
94
- return constrain(mappedValue, outMin, outMax);
95
-}
96
-
97
-void loop() {
98
- // Read mapped control signals from each channel
99
- aileronControl = readAileronControlSignal(); // Throttle (0-100)
100
- elevatorControl = readElevatorControlSignal(); // Steering (0-100)
101
-
102
- // Print the mapped control signal values to the Serial Monitor
103
- Serial.print("Aileron (Throttle): ");
104
- Serial.print(aileronControl);
105
- Serial.print(" Elevator (Steering): ");
106
- Serial.print(elevatorControl);
107
- Serial.println();
108
-
109
- // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input)
110
- // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0.
111
- int deadbandRadius = 5;
112
- float steeringFactor = 1.5; // Adjust this value to change steering sensitivity
113
- float throttleFactor = 1.3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle)
114
-
115
- // Map control values with deadband
116
- long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255);
117
- long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255);
118
-
119
- // Apply sensitivity factors
120
- long throttleValue = rawThrottleValue * throttleFactor;
121
- long adjustedSteeringValue = rawSteeringValue * steeringFactor;
122
-
123
- // Mix throttle and steering for differential drive
124
- long motor1Pwm = throttleValue + adjustedSteeringValue;
125
- long motor2Pwm = throttleValue - adjustedSteeringValue;
126
-
127
- // Constrain PWM values to the valid range [-255, 255]
128
- motor1Pwm = constrain(motor1Pwm, -255, 255);
129
- motor2Pwm = constrain(motor2Pwm, -255, 255);
130
-
131
- // Set motor speeds and directions
132
- setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
133
- setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
134
-
135
- delay(20); // Shorter delay for better responsiveness
136
-}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-aircraft-dat/PWM-1ch.ino
... ...
@@ -0,0 +1,74 @@
1
+// Define pins for each RC channel
2
+int aileronPin = 2; // Channel 1
3
+
4
+const int ENA = 5; // PWM for speed for Motor 1
5
+const int ENB = 4; // PWM for speed for Motor 2
6
+
7
+const int IN1 = 0; // Direction for Motor 1 (IN2_Motor1 is inverted in hardware)
8
+const int IN2 = 2; // Direction pin 1 for Motor 2
9
+
10
+long aileronControl;
11
+
12
+long readAileronControlSignal() {
13
+ unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
14
+ if (rawPWM == 0) { // Timeout or no signal
15
+ return 50; // Mid-point for 0-100 scale (1500us equivalent)
16
+ }
17
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
18
+ return map(constrainedPWM, 1000, 2000, 0, 100);
19
+}
20
+
21
+void setup() {
22
+ pinMode(aileronPin, INPUT);
23
+
24
+ pinMode(ENA, OUTPUT);
25
+ pinMode(ENB, OUTPUT);
26
+ pinMode(IN1, OUTPUT);
27
+ pinMode(IN2, OUTPUT);
28
+
29
+ // Initialize motors to off
30
+ digitalWrite(IN1, LOW);
31
+ digitalWrite(IN2, LOW);
32
+ analogWrite(ENA, 0);
33
+ analogWrite(ENB, 0);
34
+
35
+ Serial.begin(9600);
36
+}
37
+
38
+void loop() {
39
+ // Read mapped control signals from each channel
40
+ aileronControl = readAileronControlSignal();
41
+
42
+ // Print the mapped control signal values to the Serial Monitor
43
+ Serial.print("Aileron: ");
44
+ Serial.print(aileronControl);
45
+ Serial.println(); // Newline for better readability
46
+
47
+ if (aileronControl > 70) {
48
+ // Forward
49
+ digitalWrite(IN1, HIGH); // Motor 1 forward
50
+ digitalWrite(IN2, HIGH); // Motor 2 forward
51
+
52
+ // Map aileronControl (61-100) to PWM speed (e.g., 100-255)
53
+ int motorSpeed = map(aileronControl, 61, 100, 100, 255);
54
+ analogWrite(ENA, motorSpeed);
55
+ analogWrite(ENB, motorSpeed);
56
+ } else if (aileronControl < 30) {
57
+ // Backward
58
+ digitalWrite(IN1, LOW); // Motor 1 backward
59
+ digitalWrite(IN2, LOW); // Motor 2 backward
60
+
61
+ // Map aileronControl (0-39) to PWM speed (e.g., 255-100, reversing the range for backward)
62
+ int motorSpeed = map(aileronControl, 0, 39, 255, 100);
63
+ analogWrite(ENA, motorSpeed);
64
+ analogWrite(ENB, motorSpeed);
65
+ } else {
66
+ // Stop motors (aileronControl is between 40 and 60 inclusive)
67
+ digitalWrite(IN1, LOW);
68
+ digitalWrite(IN2, LOW);
69
+ analogWrite(ENA, 0);
70
+ analogWrite(ENB, 0);
71
+ }
72
+
73
+ delay(100); // Limit output rate
74
+}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-aircraft-dat/PWM-2ch-2.ino
... ...
@@ -0,0 +1,142 @@
1
+// Define pins for each RC channel
2
+int aileronPin = 14; // Channel 1 (Throttle)
3
+int elevatorPin = 12; // Channel 2 (Steering)
4
+
5
+const int ENA = 5; // PWM for speed for Motor 1
6
+const int ENB = 4; // PWM for speed for Motor 2
7
+
8
+const int IN1 = 0; // Direction for Motor 1
9
+const int IN2 = 2; // Direction pin 1 for Motor 2
10
+
11
+long aileronControl; // Mapped value from aileron channel (0-100)
12
+long elevatorControl; // Mapped value from elevator channel (0-100)
13
+
14
+// Reads the PWM signal from the aileron channel and maps it to 0-100
15
+long readAileronControlSignal() {
16
+ unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
17
+ // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
18
+ // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
19
+ if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
20
+ return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
21
+ }
22
+ // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
23
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
24
+ return map(constrainedPWM, 1000, 2000, 0, 100);
25
+}
26
+
27
+// Reads the PWM signal from the elevator channel and maps it to 0-100
28
+long readElevatorControlSignal() {
29
+ unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
30
+ // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
31
+ // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
32
+ if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
33
+ return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
34
+ }
35
+ // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
36
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
37
+ return map(constrainedPWM, 1000, 2000, 0, 100);
38
+}
39
+
40
+void setup() {
41
+ pinMode(aileronPin, INPUT);
42
+ pinMode(elevatorPin, INPUT); // Initialize elevator pin
43
+
44
+ pinMode(ENA, OUTPUT);
45
+ pinMode(ENB, OUTPUT);
46
+ pinMode(IN1, OUTPUT);
47
+ pinMode(IN2, OUTPUT);
48
+
49
+ // Initialize motors to off
50
+ digitalWrite(IN1, LOW);
51
+ digitalWrite(IN2, LOW);
52
+ analogWrite(ENA, 0);
53
+ analogWrite(ENB, 0);
54
+
55
+ Serial.begin(9600);
56
+}
57
+
58
+// Helper function to control a single motor
59
+// pwmVal: -255 (full backward) to 255 (full forward)
60
+void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
61
+ if (pwmVal > 0) { // Forward
62
+ digitalWrite(dirPin, HIGH);
63
+ analogWrite(speedPin, pwmVal);
64
+ } else if (pwmVal < 0) { // Backward
65
+ digitalWrite(dirPin, LOW);
66
+ analogWrite(speedPin, -pwmVal); // Speed is positive
67
+ } else { // Stop
68
+ digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0
69
+ analogWrite(speedPin, 0);
70
+ }
71
+}
72
+
73
+// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255)
74
+// with a deadband around the center (e.g., 50).
75
+long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) {
76
+ long mappedValue = 0;
77
+ int deadbandLower = rcCenter - deadbandRadius;
78
+ int deadbandUpper = rcCenter + deadbandRadius;
79
+
80
+ if (rcValue < deadbandLower) {
81
+ // Map the range [rcMin, deadbandLower - 1] to [outMin, -1]
82
+ // Ensure deadbandLower - 1 is not less than rcMin
83
+ if (deadbandLower -1 < rcMin) {
84
+ mappedValue = outMin;
85
+ } else {
86
+ mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1);
87
+ }
88
+ } else if (rcValue > deadbandUpper) {
89
+ // Map the range [deadbandUpper + 1, rcMax] to [1, outMax]
90
+ // Ensure deadbandUpper + 1 is not greater than rcMax
91
+ if (deadbandUpper + 1 > rcMax) {
92
+ mappedValue = outMax;
93
+ } else {
94
+ mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax);
95
+ }
96
+ } else {
97
+ // Inside deadband
98
+ mappedValue = 0;
99
+ }
100
+ return constrain(mappedValue, outMin, outMax);
101
+}
102
+
103
+void loop() {
104
+ // Read mapped control signals from each channel
105
+ aileronControl = readAileronControlSignal(); // Throttle (0-100)
106
+ elevatorControl = readElevatorControlSignal(); // Steering (0-100)
107
+
108
+ // Print the mapped control signal values to the Serial Monitor
109
+ Serial.print("Aileron (Throttle): ");
110
+ Serial.print(aileronControl);
111
+ Serial.print(" Elevator (Steering): ");
112
+ Serial.print(elevatorControl);
113
+ Serial.println();
114
+
115
+ // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input)
116
+ // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0.
117
+ int deadbandRadius = 10;
118
+ float steeringFactor = 3; // Adjust this value to change steering sensitivity
119
+ float throttleFactor = 3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle)
120
+
121
+ // Map control values with deadband
122
+ long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255);
123
+ long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255);
124
+
125
+ // Apply sensitivity factors
126
+ long throttleValue = rawThrottleValue * throttleFactor;
127
+ long adjustedSteeringValue = rawSteeringValue * steeringFactor;
128
+
129
+ // Mix throttle and steering for differential drive
130
+ long motor1Pwm = throttleValue + adjustedSteeringValue;
131
+ long motor2Pwm = throttleValue - adjustedSteeringValue;
132
+
133
+ // Constrain PWM values to the valid range [-255, 255]
134
+ motor1Pwm = constrain(motor1Pwm, -255, 255);
135
+ motor2Pwm = constrain(motor2Pwm, -255, 255);
136
+
137
+ // Set motor speeds and directions
138
+ setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
139
+ setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
140
+
141
+ delay(20); // Shorter delay for better responsiveness
142
+}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-aircraft-dat/PWM-2ch-v2.ino
... ...
@@ -0,0 +1,68 @@
1
+// RC signal input pins
2
+#define THROTTLE_PIN 2 // Channel 1 (forward/back)
3
+#define STEERING_PIN 3 // Channel 2 (left/right)
4
+
5
+// Motor control pins (L298N)
6
+#define LEFT_ENA 9
7
+#define LEFT_IN1 4
8
+#define LEFT_IN2 5
9
+
10
+#define RIGHT_ENB 10
11
+#define RIGHT_IN3 6
12
+#define RIGHT_IN4 7
13
+
14
+int throttle, steering;
15
+
16
+void setup() {
17
+ pinMode(THROTTLE_PIN, INPUT);
18
+ pinMode(STEERING_PIN, INPUT);
19
+
20
+ pinMode(LEFT_IN1, OUTPUT);
21
+ pinMode(LEFT_IN2, OUTPUT);
22
+ pinMode(LEFT_ENA, OUTPUT);
23
+
24
+ pinMode(RIGHT_IN3, OUTPUT);
25
+ pinMode(RIGHT_IN4, OUTPUT);
26
+ pinMode(RIGHT_ENB, OUTPUT);
27
+
28
+ Serial.begin(9600);
29
+}
30
+
31
+void loop() {
32
+ // Read PWM input
33
+ throttle = pulseIn(THROTTLE_PIN, HIGH, 25000);
34
+ steering = pulseIn(STEERING_PIN, HIGH, 25000);
35
+
36
+ // Center = 1500, range = 1000–2000
37
+ int throttleVal = map(throttle, 1000, 2000, -255, 255);
38
+ int steeringVal = map(steering, 1000, 2000, -100, 100); // less aggressive
39
+
40
+ // Motor mixing (differential drive)
41
+ int leftSpeed = constrain(throttleVal + steeringVal, -255, 255);
42
+ int rightSpeed = constrain(throttleVal - steeringVal, -255, 255);
43
+
44
+ setMotor(LEFT_IN1, LEFT_IN2, LEFT_ENA, leftSpeed);
45
+ setMotor(RIGHT_IN3, RIGHT_IN4, RIGHT_ENB, rightSpeed);
46
+
47
+ // Debug
48
+ Serial.print("Throttle: "); Serial.print(throttleVal);
49
+ Serial.print(" Steering: "); Serial.print(steeringVal);
50
+ Serial.print(" L: "); Serial.print(leftSpeed);
51
+ Serial.print(" R: "); Serial.println(rightSpeed);
52
+
53
+ delay(20);
54
+}
55
+
56
+void setMotor(int in1, int in2, int ena, int speed) {
57
+ if (speed > 0) {
58
+ digitalWrite(in1, HIGH);
59
+ digitalWrite(in2, LOW);
60
+ } else if (speed < 0) {
61
+ digitalWrite(in1, LOW);
62
+ digitalWrite(in2, HIGH);
63
+ } else {
64
+ digitalWrite(in1, LOW);
65
+ digitalWrite(in2, LOW);
66
+ }
67
+ analogWrite(ena, abs(speed));
68
+}
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-aircraft-dat/SDR1064-1.ino
... ...
@@ -0,0 +1,94 @@
1
+// Define pins for each RC channel
2
+int aileronPin = 14; // Channel 1 (Throttle)
3
+int elevatorPin = 12; // Channel 2 (Steering)
4
+
5
+const int ENA = 5; // PWM for speed for Motor 1
6
+const int ENB = 4; // PWM for speed for Motor 2
7
+
8
+const int IN1 = 0; // Direction for Motor 1
9
+const int IN2 = 2; // Direction pin 1 for Motor 2
10
+
11
+long aileronControl; // Mapped value from aileron channel (0-100)
12
+long elevatorControl; // Mapped value from elevator channel (0-100)
13
+
14
+// Reads the PWM signal from the aileron channel and maps it to 0-100
15
+long readAileronControlSignal() {
16
+ unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
17
+ // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
18
+ if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
19
+ return 50; // Mid-point for 0-100 scale
20
+ }
21
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
22
+ return map(constrainedPWM, 1000, 2000, 0, 100);
23
+}
24
+
25
+// Reads the PWM signal from the elevator channel and maps it to 0-100
26
+long readElevatorControlSignal() {
27
+ unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
28
+ // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
29
+ if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
30
+ return 50; // Mid-point for 0-100 scale
31
+ }
32
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
33
+ return map(constrainedPWM, 1000, 2000, 0, 100);
34
+}
35
+
36
+void setup() {
37
+ pinMode(aileronPin, INPUT);
38
+ pinMode(elevatorPin, INPUT);
39
+
40
+ pinMode(ENA, OUTPUT);
41
+ pinMode(ENB, OUTPUT);
42
+ pinMode(IN1, OUTPUT);
43
+ pinMode(IN2, OUTPUT);
44
+
45
+ // Initialize motors to off
46
+ digitalWrite(IN1, LOW);
47
+ digitalWrite(IN2, LOW);
48
+ analogWrite(ENA, 0);
49
+ analogWrite(ENB, 0);
50
+}
51
+
52
+// Helper function to control a single motor
53
+// pwmVal: -255 (full backward) to 255 (full forward)
54
+void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
55
+ if (pwmVal > 0) { // Forward
56
+ digitalWrite(dirPin, HIGH);
57
+ analogWrite(speedPin, pwmVal);
58
+ } else if (pwmVal < 0) { // Backward
59
+ digitalWrite(dirPin, LOW);
60
+ analogWrite(speedPin, -pwmVal); // Speed is positive
61
+ } else { // Stop
62
+ digitalWrite(dirPin, LOW);
63
+ analogWrite(speedPin, 0);
64
+ }
65
+}
66
+
67
+void loop() {
68
+ // Read mapped control signals from each channel
69
+ aileronControl = readAileronControlSignal(); // Throttle (0-100, 50 is neutral)
70
+ elevatorControl = readElevatorControlSignal(); // Steering (0-100, 50 is neutral)
71
+
72
+ // Map control values directly
73
+ // aileronControl (0-100) to throttleValue (-255 to 255)
74
+ // 0 -> -255 (full reverse), 50 -> 0 (stop), 100 -> 255 (full forward)
75
+ long throttleValue = map(aileronControl, 0, 100, -255, 255);
76
+
77
+ // elevatorControl (0-100) to steeringValue (-255 to 255)
78
+ // 0 -> -255 (full left turn effect), 50 -> 0 (straight), 100 -> 255 (full right turn effect)
79
+ long steeringValue = map(elevatorControl, 0, 100, -255, 255);
80
+
81
+ // Mix throttle and steering for differential drive
82
+ long motor1Pwm = throttleValue + steeringValue;
83
+ long motor2Pwm = throttleValue - steeringValue;
84
+
85
+ // Constrain PWM values to the valid range [-255, 255]
86
+ motor1Pwm = constrain(motor1Pwm, -255, 255);
87
+ motor2Pwm = constrain(motor2Pwm, -255, 255);
88
+
89
+ // Set motor speeds and directions
90
+ setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
91
+ setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
92
+
93
+ delay(20); // Delay for responsiveness
94
+}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-aircraft-dat/SDR1064-2.ino
... ...
@@ -0,0 +1,167 @@
1
+#include <Adafruit_NeoPixel.h>
2
+
3
+// Define pins for each RC channel
4
+int aileronPin = 14; // Channel 1 (Throttle) // D5
5
+int elevatorPin = 12; // Channel 2 (Steering) // D6
6
+
7
+const int IN1 = 0; // Direction for Motor 1 // D3
8
+const int IN2 = 2; // Direction pin 1 for Motor 2 // D4
9
+
10
+// WS2812 LED Strip Configuration
11
+#define LED_PIN 15 // nodemcu pin D8
12
+#define LED_COUNT 8
13
+Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
14
+
15
+long aileronControl; // Mapped value from aileron channel (0-100)
16
+long elevatorControl; // Mapped value from elevator channel (0-100)
17
+
18
+// Reads the PWM signal from the aileron channel and maps it to 0-100
19
+long readAileronControlSignal() {
20
+ unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
21
+ // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
22
+ // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
23
+ if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
24
+ return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
25
+ }
26
+ // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
27
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
28
+ return map(constrainedPWM, 1000, 2000, 0, 100);
29
+}
30
+
31
+// Reads the PWM signal from the elevator channel and maps it to 0-100
32
+long readElevatorControlSignal() {
33
+ unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
34
+ // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50)
35
+ // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid.
36
+ if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) {
37
+ return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop
38
+ }
39
+ // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map
40
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
41
+ return map(constrainedPWM, 1000, 2000, 0, 100);
42
+}
43
+
44
+void setup() {
45
+ pinMode(aileronPin, INPUT);
46
+ pinMode(elevatorPin, INPUT); // Initialize elevator pin
47
+
48
+ pinMode(ENA, OUTPUT);
49
+ pinMode(ENB, OUTPUT);
50
+ pinMode(IN1, OUTPUT);
51
+ pinMode(IN2, OUTPUT);
52
+
53
+ // Initialize motors to off
54
+ digitalWrite(IN1, LOW);
55
+ digitalWrite(IN2, LOW);
56
+ analogWrite(ENA, 0);
57
+ analogWrite(ENB, 0);
58
+
59
+ Serial.begin(9600);
60
+
61
+ strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
62
+ strip.show(); // Turn OFF all pixels ASAP
63
+ strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
64
+}
65
+
66
+// Helper function to control a single motor
67
+// pwmVal: -255 (full backward) to 255 (full forward)
68
+void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
69
+ if (pwmVal > 0) { // Forward
70
+ digitalWrite(dirPin, HIGH);
71
+ analogWrite(speedPin, pwmVal);
72
+ } else if (pwmVal < 0) { // Backward
73
+ digitalWrite(dirPin, LOW);
74
+ analogWrite(speedPin, -pwmVal); // Speed is positive
75
+ } else { // Stop
76
+ digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0
77
+ analogWrite(speedPin, 0);
78
+ }
79
+}
80
+
81
+// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255)
82
+// with a deadband around the center (e.g., 50).
83
+long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) {
84
+ long mappedValue = 0;
85
+ int deadbandLower = rcCenter - deadbandRadius;
86
+ int deadbandUpper = rcCenter + deadbandRadius;
87
+
88
+ if (rcValue < deadbandLower) {
89
+ // Map the range [rcMin, deadbandLower - 1] to [outMin, -1]
90
+ // Ensure deadbandLower - 1 is not less than rcMin
91
+ if (deadbandLower -1 < rcMin) {
92
+ mappedValue = outMin;
93
+ } else {
94
+ mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1);
95
+ }
96
+ } else if (rcValue > deadbandUpper) {
97
+ // Map the range [deadbandUpper + 1, rcMax] to [1, outMax]
98
+ // Ensure deadbandUpper + 1 is not greater than rcMax
99
+ if (deadbandUpper + 1 > rcMax) {
100
+ mappedValue = outMax;
101
+ } else {
102
+ mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax);
103
+ }
104
+ } else {
105
+ // Inside deadband
106
+ mappedValue = 0;
107
+ }
108
+ return constrain(mappedValue, outMin, outMax);
109
+}
110
+
111
+// Function to create a random blinking effect for WS2812 LEDs
112
+void randomBlinkEffect() {
113
+ for (int i = 0; i < LED_COUNT; i++) {
114
+ // Turn on a random LED with a random color
115
+ if (random(0, 2) == 1) { // 50% chance to turn on this LED
116
+ strip.setPixelColor(i, strip.Color(random(0, 256), random(0, 256), random(0, 256)));
117
+ } else {
118
+ strip.setPixelColor(i, strip.Color(0, 0, 0)); // Turn off
119
+ }
120
+ }
121
+ strip.show(); // Send the updated pixel colors to the hardware.
122
+ delay(100); // Wait a short period
123
+}
124
+
125
+void loop() {
126
+ // Read mapped control signals from each channel
127
+ aileronControl = readAileronControlSignal(); // Throttle (0-100)
128
+ elevatorControl = readElevatorControlSignal(); // Steering (0-100)
129
+
130
+ // Print the mapped control signal values to the Serial Monitor
131
+ Serial.print("Aileron (Throttle): ");
132
+ Serial.print(aileronControl);
133
+ Serial.print(" Elevator (Steering): ");
134
+ Serial.print(elevatorControl);
135
+ Serial.println();
136
+
137
+ // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input)
138
+ // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0.
139
+ int deadbandRadius = 15;
140
+ float steeringFactor = 3; // Adjust this value to change steering sensitivity
141
+ float throttleFactor = 3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle)
142
+
143
+ // Map control values with deadband
144
+ long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255);
145
+ long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255);
146
+
147
+ // Apply sensitivity factors
148
+ long throttleValue = rawThrottleValue * throttleFactor;
149
+ long adjustedSteeringValue = rawSteeringValue * steeringFactor;
150
+
151
+ // Mix throttle and steering for differential drive
152
+ long motor1Pwm = throttleValue + adjustedSteeringValue;
153
+ long motor2Pwm = throttleValue - adjustedSteeringValue;
154
+
155
+ // Constrain PWM values to the valid range [-255, 255]
156
+ motor1Pwm = constrain(motor1Pwm, -255, 255);
157
+ motor2Pwm = constrain(motor2Pwm, -255, 255);
158
+
159
+ // Set motor speeds and directions
160
+ setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
161
+ setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
162
+
163
+ // Add the LED effect
164
+ randomBlinkEffect();
165
+
166
+ delay(20); // Shorter delay for better responsiveness
167
+}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-aircraft-dat/SDR1064-3.ino
... ...
@@ -0,0 +1,136 @@
1
+// Define pins for each RC channel
2
+int aileronPin = 14; // Channel 1 (Throttle)
3
+int elevatorPin = 12; // Channel 2 (Steering)
4
+
5
+const int ENA = 5; // PWM for speed for Motor 1
6
+const int ENB = 4; // PWM for speed for Motor 2
7
+
8
+const int IN1 = 0; // Direction for Motor 1
9
+const int IN2 = 2; // Direction pin 1 for Motor 2
10
+
11
+long aileronControl; // Mapped value from aileron channel (0-100)
12
+long elevatorControl; // Mapped value from elevator channel (0-100)
13
+
14
+// Reads the PWM signal from the aileron channel and maps it to 0-100
15
+long readAileronControlSignal() {
16
+ unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000);
17
+ if (rawPWM == 0) { // Timeout or no signal
18
+ return 50; // Mid-point for 0-100 scale (1500us equivalent)
19
+ }
20
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
21
+ return map(constrainedPWM, 1000, 2000, 0, 100);
22
+}
23
+
24
+// Reads the PWM signal from the elevator channel and maps it to 0-100
25
+long readElevatorControlSignal() {
26
+ unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000);
27
+ if (rawPWM == 0) { // Timeout or no signal
28
+ return 50; // Mid-point for 0-100 scale (1500us equivalent)
29
+ }
30
+ long constrainedPWM = constrain(rawPWM, 1000, 2000);
31
+ return map(constrainedPWM, 1000, 2000, 0, 100);
32
+}
33
+
34
+void setup() {
35
+ pinMode(aileronPin, INPUT);
36
+ pinMode(elevatorPin, INPUT); // Initialize elevator pin
37
+
38
+ pinMode(ENA, OUTPUT);
39
+ pinMode(ENB, OUTPUT);
40
+ pinMode(IN1, OUTPUT);
41
+ pinMode(IN2, OUTPUT);
42
+
43
+ // Initialize motors to off
44
+ digitalWrite(IN1, LOW);
45
+ digitalWrite(IN2, LOW);
46
+ analogWrite(ENA, 0);
47
+ analogWrite(ENB, 0);
48
+
49
+ Serial.begin(9600);
50
+}
51
+
52
+// Helper function to control a single motor
53
+// pwmVal: -255 (full backward) to 255 (full forward)
54
+void setMotorOutput(int dirPin, int speedPin, int pwmVal) {
55
+ if (pwmVal > 0) { // Forward
56
+ digitalWrite(dirPin, HIGH);
57
+ analogWrite(speedPin, pwmVal);
58
+ } else if (pwmVal < 0) { // Backward
59
+ digitalWrite(dirPin, LOW);
60
+ analogWrite(speedPin, -pwmVal); // Speed is positive
61
+ } else { // Stop
62
+ digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0
63
+ analogWrite(speedPin, 0);
64
+ }
65
+}
66
+
67
+// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255)
68
+// with a deadband around the center (e.g., 50).
69
+long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) {
70
+ long mappedValue = 0;
71
+ int deadbandLower = rcCenter - deadbandRadius;
72
+ int deadbandUpper = rcCenter + deadbandRadius;
73
+
74
+ if (rcValue < deadbandLower) {
75
+ // Map the range [rcMin, deadbandLower - 1] to [outMin, -1]
76
+ // Ensure deadbandLower - 1 is not less than rcMin
77
+ if (deadbandLower -1 < rcMin) {
78
+ mappedValue = outMin;
79
+ } else {
80
+ mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1);
81
+ }
82
+ } else if (rcValue > deadbandUpper) {
83
+ // Map the range [deadbandUpper + 1, rcMax] to [1, outMax]
84
+ // Ensure deadbandUpper + 1 is not greater than rcMax
85
+ if (deadbandUpper + 1 > rcMax) {
86
+ mappedValue = outMax;
87
+ } else {
88
+ mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax);
89
+ }
90
+ } else {
91
+ // Inside deadband
92
+ mappedValue = 0;
93
+ }
94
+ return constrain(mappedValue, outMin, outMax);
95
+}
96
+
97
+void loop() {
98
+ // Read mapped control signals from each channel
99
+ aileronControl = readAileronControlSignal(); // Throttle (0-100)
100
+ elevatorControl = readElevatorControlSignal(); // Steering (0-100)
101
+
102
+ // Print the mapped control signal values to the Serial Monitor
103
+ Serial.print("Aileron (Throttle): ");
104
+ Serial.print(aileronControl);
105
+ Serial.print(" Elevator (Steering): ");
106
+ Serial.print(elevatorControl);
107
+ Serial.println();
108
+
109
+ // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input)
110
+ // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0.
111
+ int deadbandRadius = 5;
112
+ float steeringFactor = 1.5; // Adjust this value to change steering sensitivity
113
+ float throttleFactor = 1.3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle)
114
+
115
+ // Map control values with deadband
116
+ long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255);
117
+ long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255);
118
+
119
+ // Apply sensitivity factors
120
+ long throttleValue = rawThrottleValue * throttleFactor;
121
+ long adjustedSteeringValue = rawSteeringValue * steeringFactor;
122
+
123
+ // Mix throttle and steering for differential drive
124
+ long motor1Pwm = throttleValue + adjustedSteeringValue;
125
+ long motor2Pwm = throttleValue - adjustedSteeringValue;
126
+
127
+ // Constrain PWM values to the valid range [-255, 255]
128
+ motor1Pwm = constrain(motor1Pwm, -255, 255);
129
+ motor2Pwm = constrain(motor2Pwm, -255, 255);
130
+
131
+ // Set motor speeds and directions
132
+ setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1
133
+ setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2
134
+
135
+ delay(20); // Shorter delay for better responsiveness
136
+}
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-rover-code-dat/SDR1064-rover-code-dat.md
... ...
@@ -0,0 +1,14 @@
1
+
2
+# SDR1064-rover-code-dat.md
3
+
4
+## working for
5
+
6
+- [[SDR1064-dat]] - [[nodemcu-dat]]
7
+
8
+- [[serial-motor-1.ino]] - [[motor-1-wifi-ap.ino]]
9
+
10
+
11
+
12
+## ref
13
+
14
+- [[rc-code-dat]]
... ...
\ No newline at end of file
code-dat/RC-code-dat/SDR1064-code-dat/SDR1064-rover-code-dat/motor-1-wifi-ap.ino
... ...
@@ -0,0 +1,120 @@
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/SDR1064-code-dat/SDR1064-rover-code-dat/serial-motor-1.ino
... ...
@@ -0,0 +1,76 @@
1
+// Define pins for motor control
2
+const int ENA = 5; // PWM for speed for Motor (single motor)
3
+
4
+const int IN1 = 0; // Direction pin A for Motor
5
+const int IN2 = 2 // Direction pin B for Motor
6
+
7
+int motorControl = 50; // 0..100, default mid-point
8
+
9
+int readControlSignal() {
10
+ // Read control value from Serial if available (expects an integer 0-100 followed by newline)
11
+ if (Serial.available()) {
12
+ String s = Serial.readStringUntil('\n');
13
+ s.trim();
14
+ if (s.length() > 0) {
15
+ int val = s.toInt();
16
+ if (val >= 0 && val <= 100) {
17
+ motorControl = val;
18
+ }
19
+ }
20
+ }
21
+ return motorControl;
22
+}
23
+
24
+void setup() {
25
+ // No RC input pin used — control comes from Serial
26
+
27
+ pinMode(ENA, OUTPUT);
28
+ pinMode(IN1, OUTPUT);
29
+ pinMode(IN2, OUTPUT);
30
+
31
+ // Initialize motor to off
32
+ digitalWrite(IN1, LOW);
33
+ digitalWrite(IN2, LOW);
34
+ analogWrite(ENA, 0);
35
+
36
+ Serial.begin(9600);
37
+ Serial.println("Motor control ready. Send 0-100 via serial to control speed/direction.");
38
+}
39
+
40
+void loop() {
41
+ // Read mapped control signal (from Serial)
42
+ motorControl = readControlSignal();
43
+
44
+ // Print the mapped control signal values to the Serial Monitor
45
+ Serial.print("Control: ");
46
+ Serial.print(motorControl);
47
+ Serial.println(); // Newline for better readability
48
+
49
+ // Deadband: treat 40..60 as stop (adjust if needed)
50
+ if (motorControl > 60) {
51
+ // Forward: IN1 = HIGH, IN2 = LOW
52
+ digitalWrite(IN1, HIGH);
53
+ digitalWrite(IN2, LOW);
54
+
55
+ // Map motorControl (61-100) to PWM speed (0-255)
56
+ int motorSpeed = map(motorControl, 61, 100, 0, 255);
57
+ motorSpeed = constrain(motorSpeed, 0, 255);
58
+ analogWrite(ENA, motorSpeed);
59
+ } else if (motorControl < 40) {
60
+ // Reverse: IN1 = LOW, IN2 = HIGH
61
+ digitalWrite(IN1, LOW);
62
+ digitalWrite(IN2, HIGH);
63
+
64
+ // Map motorControl (0-39) to PWM speed (0-255)
65
+ int motorSpeed = map(motorControl, 0, 39, 0, 255);
66
+ motorSpeed = constrain(motorSpeed, 0, 255);
67
+ analogWrite(ENA, motorSpeed);
68
+ } else {
69
+ // Stop motor (motorControl is between 40 and 60 inclusive)
70
+ digitalWrite(IN1, LOW);
71
+ digitalWrite(IN2, LOW);
72
+ analogWrite(ENA, 0);
73
+ }
74
+
75
+ delay(100); // Limit output rate
76
+}
... ...
\ No newline at end of file
code-dat/code-dat.md
... ...
@@ -0,0 +1,13 @@
1
+
2
+# code-dat.md
3
+
4
+- [[RC-code-dat]]
5
+
6
+- [[wifi-motor-control-dat]] - [[wifi-dat]] - [[SDR1064-dat]]
7
+
8
+- [[motor-driver-code-dat]]
9
+
10
+
11
+## repo
12
+
13
+- [[arduino-dat]]
... ...
\ No newline at end of file
code-dat/motor-driver-code-dat/PWM-motor-esp-webserver-ap-1.ino
... ...
@@ -0,0 +1,98 @@
1
+#include <ESP8266WiFi.h>
2
+#include <ESP8266WebServer.h>
3
+
4
+// ===== WiFi 配置 =====
5
+const char* ssid = "YOUR_SSID";
6
+const char* password = "YOUR_PASSWORD";
7
+
8
+// ===== GPIO 定义 =====
9
+const int PWM_PIN = D1; // PWM 控制速度 IO5
10
+const int DIR_PIN1 = D2; // 方向引脚1 IO4
11
+const int DIR_PIN2 = D3; // 方向引脚2 IO0
12
+
13
+// ===== Web Server =====
14
+ESP8266WebServer server(80);
15
+
16
+// ===== HTML Web 控制界面 =====
17
+const char html_page[] PROGMEM = R"rawliteral(
18
+<!DOCTYPE html><html>
19
+<head><title>ESP8266 Motor Control</title></head>
20
+<body>
21
+<h2>Motor Control</h2>
22
+<form action="/control">
23
+Speed: <input type="range" name="speed" min="0" max="1023"><br>
24
+Direction:
25
+<select name="dir">
26
+ <option value="fw">Forward</option>
27
+ <option value="rv">Reverse</option>
28
+</select><br>
29
+<input type="submit" value="Apply">
30
+</form>
31
+</body></html>
32
+)rawliteral";
33
+
34
+// ===== 处理 Web 请求 =====
35
+void handleRoot() {
36
+ server.send(200, "text/html", html_page);
37
+}
38
+
39
+void handleControl() {
40
+ if (server.hasArg("speed")) {
41
+ int speed = server.arg("speed").toInt(); // PWM 值 0-1023
42
+ analogWrite(PWM_PIN, speed);
43
+ }
44
+
45
+ if (server.hasArg("dir")) {
46
+ String d = server.arg("dir");
47
+ if (d == "fw") {
48
+ digitalWrite(DIR_PIN1, HIGH);
49
+ digitalWrite(DIR_PIN2, LOW);
50
+ } else {
51
+ digitalWrite(DIR_PIN1, LOW);
52
+ digitalWrite(DIR_PIN2, HIGH);
53
+ }
54
+ }
55
+
56
+ server.sendHeader("Location", "/");
57
+ server.send(302, "text/plain", "");
58
+}
59
+
60
+// ===== 初始化 =====
61
+void setup() {
62
+ Serial.begin(115200);
63
+
64
+ pinMode(PWM_PIN, OUTPUT);
65
+ pinMode(DIR_PIN1, OUTPUT);
66
+ pinMode(DIR_PIN2, OUTPUT);
67
+
68
+ // 默认停止
69
+ analogWrite(PWM_PIN, 0);
70
+ digitalWrite(DIR_PIN1, LOW);
71
+ digitalWrite(DIR_PIN2, LOW);
72
+
73
+ // 启动为 WiFi AP 模式,使用固定 IP
74
+ WiFi.mode(WIFI_AP);
75
+ // 固定 AP 地址(根据需要修改)
76
+ IPAddress apIP(192, 168, 50, 1);
77
+ IPAddress apGateway(192, 168, 50, 1);
78
+ IPAddress apSubnet(255, 255, 255, 0);
79
+ if (!WiFi.softAPConfig(apIP, apGateway, apSubnet)) {
80
+ Serial.println("softAPConfig failed");
81
+ }
82
+
83
+ // 启动软 AP:使用 ssid 和 password(注意:WPA2 密码至少 8 字符)
84
+ WiFi.softAP(ssid, password);
85
+ delay(500);
86
+ Serial.println("");
87
+ Serial.print("AP started, IP: ");
88
+ Serial.println(WiFi.softAPIP());
89
+
90
+ // Web 服务
91
+ server.on("/", handleRoot);
92
+ server.on("/control", handleControl);
93
+ server.begin();
94
+}
95
+
96
+void loop() {
97
+ server.handleClient();
98
+}
... ...
\ No newline at end of file
code-dat/motor-driver-code-dat/PWM-motor-esp-webserver-sta-1.ino
... ...
@@ -0,0 +1,94 @@
1
+
2
+
3
+#include <ESP8266WiFi.h>
4
+#include <ESP8266WebServer.h>
5
+
6
+// ===== WiFi 配置 =====
7
+const char* ssid = "YOUR_SSID";
8
+const char* password = "YOUR_PASSWORD";
9
+
10
+// ===== GPIO 定义 =====
11
+const int PWM_PIN = D1; // PWM 控制速度 IO5
12
+const int DIR_PIN1 = D2; // 方向引脚1 IO4
13
+const int DIR_PIN2 = D3; // 方向引脚2 IO0
14
+
15
+// ===== Web Server =====
16
+ESP8266WebServer server(80);
17
+
18
+// ===== HTML Web 控制界面 =====
19
+const char html_page[] PROGMEM = R"rawliteral(
20
+<!DOCTYPE html><html>
21
+<head><title>ESP8266 Motor Control</title></head>
22
+<body>
23
+<h2>Motor Control</h2>
24
+<form action="/control">
25
+Speed: <input type="range" name="speed" min="0" max="1023"><br>
26
+Direction:
27
+<select name="dir">
28
+ <option value="fw">Forward</option>
29
+ <option value="rv">Reverse</option>
30
+</select><br>
31
+<input type="submit" value="Apply">
32
+</form>
33
+</body></html>
34
+)rawliteral";
35
+
36
+// ===== 处理 Web 请求 =====
37
+void handleRoot() {
38
+ server.send(200, "text/html", html_page);
39
+}
40
+
41
+void handleControl() {
42
+ if (server.hasArg("speed")) {
43
+ int speed = server.arg("speed").toInt(); // PWM 值 0-1023
44
+ analogWrite(PWM_PIN, speed);
45
+ }
46
+
47
+ if (server.hasArg("dir")) {
48
+ String d = server.arg("dir");
49
+ if (d == "fw") {
50
+ digitalWrite(DIR_PIN1, HIGH);
51
+ digitalWrite(DIR_PIN2, LOW);
52
+ } else {
53
+ digitalWrite(DIR_PIN1, LOW);
54
+ digitalWrite(DIR_PIN2, HIGH);
55
+ }
56
+ }
57
+
58
+ server.sendHeader("Location", "/");
59
+ server.send(302, "text/plain", "");
60
+}
61
+
62
+// ===== 初始化 =====
63
+void setup() {
64
+ Serial.begin(115200);
65
+
66
+ pinMode(PWM_PIN, OUTPUT);
67
+ pinMode(DIR_PIN1, OUTPUT);
68
+ pinMode(DIR_PIN2, OUTPUT);
69
+
70
+ // 默认停止
71
+ analogWrite(PWM_PIN, 0);
72
+ digitalWrite(DIR_PIN1, LOW);
73
+ digitalWrite(DIR_PIN2, LOW);
74
+
75
+ // 连接 WiFi
76
+ WiFi.mode(WIFI_STA);
77
+ WiFi.begin(ssid, password);
78
+ while (WiFi.status() != WL_CONNECTED) {
79
+ delay(500);
80
+ Serial.print(".");
81
+ }
82
+ Serial.println("");
83
+ Serial.print("Connected, IP: ");
84
+ Serial.println(WiFi.localIP());
85
+
86
+ // Web 服务
87
+ server.on("/", handleRoot);
88
+ server.on("/control", handleControl);
89
+ server.begin();
90
+}
91
+
92
+void loop() {
93
+ server.handleClient();
94
+}
... ...
\ No newline at end of file
code-dat/motor-driver-code-dat/motor-driver-code-dat.md
... ...
@@ -0,0 +1,22 @@
1
+
2
+# motor-driver-code-dat
3
+
4
+
5
+
6
+## drive by wifi and webserver
7
+
8
+- [[PWM-motor-esp-webserver-sta-1.ino]]
9
+
10
+- [[wifi-motor-control-dat]]
11
+
12
+- [[ESP32-rc-car-dat]]
13
+
14
+
15
+
16
+
17
+
18
+## ref
19
+
20
+- [[motor-driver-dat]]
21
+
22
+