7453ca9297ac69bd46f0a7b54beb33d7fc7fd952
Chip-cn-dat/Espressif-dat/ESP8266-chip-DAT/ESP8266-DAT.md
| ... | ... | @@ -50,6 +50,7 @@ find modules here - [[esp8266-modules-dat]] |
| 50 | 50 |  |
| 51 | 51 | |
| 52 | 52 | |
| 53 | + |
|
| 53 | 54 | ### programmer and programming |
| 54 | 55 | |
| 55 | 56 | - [[DPR1150-dat]] - [[NWI1070-dat]] for ESP-01/01S |
Chip-dat/TI-dat/TI-Motor-dat/DRV8871-dat/drv8871-1.ino
| ... | ... | @@ -0,0 +1,130 @@ |
| 1 | +// NodeMCU (ESP8266) code to drive two DC motors with DRV8871 |
|
| 2 | +// Each motor uses a single GPIO: |
|
| 3 | +// Motor 1: IO0 (D3) for IN1, and IN2 driven by IO0 via an inverter. |
|
| 4 | +// Motor 2: IO2 (D4) for IN1, and IN2 driven by IO2 via an inverter. |
|
| 5 | + |
|
| 6 | +// Define the NodeMCU pins |
|
| 7 | +// MOTOR 1 |
|
| 8 | +// GPIO0 (D3 on many NodeMCU boards) is used here. |
|
| 9 | +// WARNING: GPIO0 is a boot mode pin. If it's LOW during boot, ESP8266 enters flash mode. |
|
| 10 | +// Ensure your circuit doesn't pull GPIO0 LOW at boot unless intended. |
|
| 11 | +const int MOTOR1_CTRL_PIN = 0; // GPIO0 (D3) |
|
| 12 | + |
|
| 13 | +// MOTOR 2 |
|
| 14 | +// GPIO2 (D4 on many NodeMCU boards) is generally safe to use. |
|
| 15 | +const int MOTOR2_CTRL_PIN = 2; // GPIO2 (D4) |
|
| 16 | + |
|
| 17 | + |
|
| 18 | +// DRV8871 connections (repeat for each motor): |
|
| 19 | +// - MOTORx_CTRL_PIN to DRV8871 IN1 |
|
| 20 | +// - MOTORx_CTRL_PIN -> Inverter -> DRV8871 IN2 |
|
| 21 | +// - Motor to DRV8871 OUT1 and OUT2 |
|
| 22 | +// - Motor power supply (6.5V to 45V) to DRV8871 VM and GND |
|
| 23 | +// - NodeMCU GND to DRV8871 GND |
|
| 24 | +// - Optionally, ILIM resistor (refer to DRV8871 datasheet) |
|
| 25 | + |
|
| 26 | +// ESP8266 analogWrite range is 0-1023 by default. |
|
| 27 | +// PWM_STOP is still needed for the active stopMotor function. |
|
| 28 | +const int PWM_MAX = 1023; |
|
| 29 | +const int PWM_STOP = PWM_MAX / 2; // Approx 511 or 512, for 50% duty cycle |
|
| 30 | + |
|
| 31 | +void setup() { |
|
| 32 | + pinMode(MOTOR1_CTRL_PIN, OUTPUT); |
|
| 33 | + pinMode(MOTOR2_CTRL_PIN, OUTPUT); |
|
| 34 | + |
|
| 35 | + Serial.begin(9600); |
|
| 36 | + Serial.println("DRV8871 Dual Motor Single Pin (IO0/IO2 + Inverters) Control - Digital Direction"); |
|
| 37 | + Serial.println("Note: Stop is an active stop (50% PWM). True coast/brake not available."); |
|
| 38 | + Serial.print("PWM Stop value for active stop: "); |
|
| 39 | + Serial.println(PWM_STOP); |
|
| 40 | + |
|
| 41 | + // Ensure motors are stopped at startup |
|
| 42 | + stopMotor1(); |
|
| 43 | + stopMotor2(); |
|
| 44 | +} |
|
| 45 | + |
|
| 46 | +void loop() { |
|
| 47 | + // Simple run loop: Both motors Forward, Stop, Reverse, Stop |
|
| 48 | + Serial.println("Motor 1 & 2 Forward - Full Speed"); |
|
| 49 | + driveMotor1(true); // true for forward |
|
| 50 | + driveMotor2(true); // true for forward |
|
| 51 | + delay(2000); |
|
| 52 | + |
|
| 53 | + Serial.println("Motor 1 & 2 Stop"); |
|
| 54 | + stopMotor1(); |
|
| 55 | + stopMotor2(); |
|
| 56 | + delay(1000); |
|
| 57 | + |
|
| 58 | + Serial.println("Motor 1 & 2 Reverse - Full Speed"); |
|
| 59 | + driveMotor1(false); // false for reverse |
|
| 60 | + driveMotor2(false); // false for reverse |
|
| 61 | + delay(2000); |
|
| 62 | + |
|
| 63 | + Serial.println("Motor 1 & 2 Stop"); |
|
| 64 | + stopMotor1(); |
|
| 65 | + stopMotor2(); |
|
| 66 | + delay(1000); |
|
| 67 | + |
|
| 68 | + // Example: Motor 1 Forward, Motor 2 Reverse |
|
| 69 | + Serial.println("Motor 1 Forward, Motor 2 Reverse"); |
|
| 70 | + driveMotor1(true); |
|
| 71 | + driveMotor2(false); |
|
| 72 | + delay(2000); |
|
| 73 | + |
|
| 74 | + Serial.println("Motor 1 & 2 Stop"); |
|
| 75 | + stopMotor1(); |
|
| 76 | + stopMotor2(); |
|
| 77 | + delay(1000); |
|
| 78 | +} |
|
| 79 | + |
|
| 80 | +// --- Motor 1 Control Functions --- |
|
| 81 | + |
|
| 82 | +// Function to drive Motor 1 with digital control for direction |
|
| 83 | +// forward: true for forward (MOTOR1_CTRL_PIN HIGH), false for reverse (MOTOR1_CTRL_PIN LOW) |
|
| 84 | +void driveMotor1(bool forward) { |
|
| 85 | + if (forward) { |
|
| 86 | + digitalWrite(MOTOR1_CTRL_PIN, HIGH); |
|
| 87 | + // Serial.println("Driving Motor 1: Forward (MOTOR1_CTRL_PIN HIGH)"); |
|
| 88 | + } else { |
|
| 89 | + digitalWrite(MOTOR1_CTRL_PIN, LOW); |
|
| 90 | + // Serial.println("Driving Motor 1: Reverse (MOTOR1_CTRL_PIN LOW)"); |
|
| 91 | + } |
|
| 92 | +} |
|
| 93 | + |
|
| 94 | +// Function to stop Motor 1 (active stop by 50% duty cycle on MOTOR1_CTRL_PIN) |
|
| 95 | +void stopMotor1() { |
|
| 96 | + analogWrite(MOTOR1_CTRL_PIN, PWM_STOP); |
|
| 97 | + // Serial.println("Motor 1 Stop (Active - 50% PWM on MOTOR1_CTRL_PIN)"); |
|
| 98 | +} |
|
| 99 | + |
|
| 100 | +// Function to "brake" Motor 1. Performs an active stop. |
|
| 101 | +void brakeMotor1() { |
|
| 102 | + stopMotor1(); |
|
| 103 | + // Serial.println("Motor 1 Brake (Performed Active Stop)"); |
|
| 104 | +} |
|
| 105 | + |
|
| 106 | +// --- Motor 2 Control Functions --- |
|
| 107 | + |
|
| 108 | +// Function to drive Motor 2 with digital control for direction |
|
| 109 | +// forward: true for forward (MOTOR2_CTRL_PIN HIGH), false for reverse (MOTOR2_CTRL_PIN LOW) |
|
| 110 | +void driveMotor2(bool forward) { |
|
| 111 | + if (forward) { |
|
| 112 | + digitalWrite(MOTOR2_CTRL_PIN, HIGH); |
|
| 113 | + // Serial.println("Driving Motor 2: Forward (MOTOR2_CTRL_PIN HIGH)"); |
|
| 114 | + } else { |
|
| 115 | + digitalWrite(MOTOR2_CTRL_PIN, LOW); |
|
| 116 | + // Serial.println("Driving Motor 2: Reverse (MOTOR2_CTRL_PIN LOW)"); |
|
| 117 | + } |
|
| 118 | +} |
|
| 119 | + |
|
| 120 | +// Function to stop Motor 2 (active stop by 50% duty cycle on MOTOR2_CTRL_PIN) |
|
| 121 | +void stopMotor2() { |
|
| 122 | + analogWrite(MOTOR2_CTRL_PIN, PWM_STOP); |
|
| 123 | + // Serial.println("Motor 2 Stop (Active - 50% PWM on MOTOR2_CTRL_PIN)"); |
|
| 124 | +} |
|
| 125 | + |
|
| 126 | +// Function to "brake" Motor 2. Performs an active stop. |
|
| 127 | +void brakeMotor2() { |
|
| 128 | + stopMotor2(); |
|
| 129 | + // Serial.println("Motor 2 Brake (Performed Active Stop)"); |
|
| 130 | +} |
|
| ... | ... | \ No newline at end of file |
app-dat/RC-dat/RC-code-dat/RC-code-dat.md
| ... | ... | @@ -3,12 +3,17 @@ |
| 3 | 3 | |
| 4 | 4 | ## working for |
| 5 | 5 | |
| 6 | -- [[SDR1064-dat]] |
|
| 6 | +- [[SDR1064-dat]] - [[nodemcu-dat]] |
|
| 7 | 7 | |
| 8 | 8 | ## code |
| 9 | 9 | |
| 10 | 10 | - [[PWM-1ch.ino]] - [[PWM-2ch.ino]] - [[PWM-2ch-v2.ino]] |
| 11 | 11 | |
| 12 | +- [[rover-1.ino]] - [[rover-2.ino]] |
|
| 13 | + |
|
| 14 | +- [[DRV8871-dat]] |
|
| 15 | + |
|
| 16 | + |
|
| 12 | 17 | ## ref |
| 13 | 18 | |
| 14 | 19 | - [[PWM-dat]] |
app-dat/RC-dat/RC-code-dat/rover-2.ino
| ... | ... | @@ -1,18 +1,15 @@ |
| 1 | 1 | #include <Adafruit_NeoPixel.h> |
| 2 | 2 | |
| 3 | 3 | // Define pins for each RC channel |
| 4 | -int aileronPin = 14; // Channel 1 (Throttle) |
|
| 5 | -int elevatorPin = 12; // Channel 2 (Steering) |
|
| 4 | +int aileronPin = 14; // Channel 1 (Throttle) // D5 |
|
| 5 | +int elevatorPin = 12; // Channel 2 (Steering) // D6 |
|
| 6 | 6 | |
| 7 | -const int ENA = 5; // PWM for speed for Motor 1 |
|
| 8 | -const int ENB = 4; // PWM for speed for Motor 2 |
|
| 9 | - |
|
| 10 | -const int IN1 = 0; // Direction for Motor 1 |
|
| 11 | -const int IN2 = 2; // Direction pin 1 for Motor 2 |
|
| 7 | +const int IN1 = 0; // Direction for Motor 1 // D3 |
|
| 8 | +const int IN2 = 2; // Direction pin 1 for Motor 2 // D4 |
|
| 12 | 9 | |
| 13 | 10 | // WS2812 LED Strip Configuration |
| 14 | 11 | #define LED_PIN 15 // nodemcu pin D8 |
| 15 | -#define LED_COUNT 8 |
|
| 12 | +#define LED_COUNT 8 |
|
| 16 | 13 | Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); |
| 17 | 14 | |
| 18 | 15 | long aileronControl; // Mapped value from aileron channel (0-100) |
app-dat/RC-dat/RC-code-dat/rover-8871-2.ino
| ... | ... | @@ -0,0 +1,257 @@ |
| 1 | +// NodeMCU (ESP8266) code to drive two DC motors with DRV8871 |
|
| 2 | +// Each motor uses a single GPIO: |
|
| 3 | +// Motor 1: IO0 (D3) for IN1, and IN2 driven by IO0 via an inverter. |
|
| 4 | +// Motor 2: IO2 (D4) for IN1, and IN2 driven by IO2 via an inverter. |
|
| 5 | + |
|
| 6 | +#include <Adafruit_NeoPixel.h> |
|
| 7 | + |
|
| 8 | +// Define pins for each RC channel |
|
| 9 | +int aileronPin = 14; // Channel 1 (Throttle) // D5 |
|
| 10 | +int elevatorPin = 12; // Channel 2 (Steering) // D6 |
|
| 11 | + |
|
| 12 | +// --- START: Added/Modified from drv8871-rc.ino --- |
|
| 13 | +// Define the NodeMCU pins for motors (consistent with drv8871-rc.ino) |
|
| 14 | +// MOTOR 1 |
|
| 15 | +// GPIO0 (D3 on many NodeMCU boards) is used here. |
|
| 16 | +// WARNING: GPIO0 is a boot mode pin. If it's LOW during boot, ESP8266 enters flash mode. |
|
| 17 | +// Ensure your circuit doesn't pull GPIO0 LOW at boot unless intended. |
|
| 18 | +const int MOTOR1_CTRL_PIN = 0; // GPIO0 (D3), replaces IN1 |
|
| 19 | + |
|
| 20 | +// MOTOR 2 |
|
| 21 | +// GPIO2 (D4 on many NodeMCU boards) is generally safe to use. |
|
| 22 | +const int MOTOR2_CTRL_PIN = 2; // GPIO2 (D4), replaces IN2 |
|
| 23 | + |
|
| 24 | +// ESP8266 analogWrite range is 0-1023 by default. |
|
| 25 | +// PWM_STOP is still needed for the active stopMotor function. |
|
| 26 | +const int PWM_MAX = 1023; |
|
| 27 | +const int PWM_STOP = PWM_MAX / 2; // Approx 511 or 512, for 50% duty cycle |
|
| 28 | +// --- END: Added/Modified from drv8871-rc.ino --- |
|
| 29 | + |
|
| 30 | +// WS2812 LED Strip Configuration |
|
| 31 | +#define LED_PIN 15 // nodemcu pin D8 |
|
| 32 | +#define LED_COUNT 8 |
|
| 33 | +Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); |
|
| 34 | + |
|
| 35 | +long aileronControl; // Mapped value from aileron channel (0-100) |
|
| 36 | +long elevatorControl; // Mapped value from elevator channel (0-100) |
|
| 37 | + |
|
| 38 | +// Reads the PWM signal from the aileron channel and maps it to 0-100 |
|
| 39 | +long readAileronControlSignal() { |
|
| 40 | + unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000); |
|
| 41 | + // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50) |
|
| 42 | + // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid. |
|
| 43 | + if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) { |
|
| 44 | + return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 45 | + } |
|
| 46 | + // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 47 | + long constrainedPWM = constrain(rawPWM, 1000, 2000); |
|
| 48 | + return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 49 | +} |
|
| 50 | + |
|
| 51 | +// Reads the PWM signal from the elevator channel and maps it to 0-100 |
|
| 52 | +long readElevatorControlSignal() { |
|
| 53 | + unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000); |
|
| 54 | + // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50) |
|
| 55 | + // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid. |
|
| 56 | + if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) { |
|
| 57 | + return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 58 | + } |
|
| 59 | + // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 60 | + long constrainedPWM = constrain(rawPWM, 1000, 2000); |
|
| 61 | + return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 62 | +} |
|
| 63 | + |
|
| 64 | +void setup() { |
|
| 65 | + pinMode(aileronPin, INPUT); |
|
| 66 | + pinMode(elevatorPin, INPUT); // Initialize elevator pin |
|
| 67 | + |
|
| 68 | + // --- START: Modified for drv8871-rc.ino motor control --- |
|
| 69 | + pinMode(MOTOR1_CTRL_PIN, OUTPUT); |
|
| 70 | + pinMode(MOTOR2_CTRL_PIN, OUTPUT); |
|
| 71 | + analogWrite(MOTOR2_CTRL_PIN, PWM_STOP); |
|
| 72 | + // --- END: Modified for drv8871-rc.ino motor control --- |
|
| 73 | + |
|
| 74 | + Serial.begin(9600); |
|
| 75 | + // --- START: Added/Modified from drv8871-rc.ino setup --- |
|
| 76 | + Serial.println("RC Rover with DRV8871 Single Pin Control"); |
|
| 77 | + Serial.println("Note: Stop is an active stop (50% PWM)."); |
|
| 78 | + Serial.print("PWM Stop value for active stop: "); |
|
| 79 | + Serial.println(PWM_STOP); |
|
| 80 | + |
|
| 81 | + // Ensure motors are stopped at startup |
|
| 82 | + stopMotor1(); |
|
| 83 | + stopMotor2(); |
|
| 84 | + // --- END: Added/Modified from drv8871-rc.ino setup --- |
|
| 85 | + |
|
| 86 | + strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) |
|
| 87 | + strip.show(); // Turn OFF all pixels ASAP |
|
| 88 | + strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) |
|
| 89 | +} |
|
| 90 | + |
|
| 91 | +// --- START: Motor control functions from drv8871-rc.ino --- |
|
| 92 | +// --- Motor 1 Control Functions --- |
|
| 93 | +// Function to drive Motor 1 with digital control for direction |
|
| 94 | +// forward: true for forward (MOTOR1_CTRL_PIN HIGH), false for reverse (MOTOR1_CTRL_PIN LOW) |
|
| 95 | +void driveMotor1(bool forward) { |
|
| 96 | + if (forward) { |
|
| 97 | + digitalWrite(MOTOR1_CTRL_PIN, HIGH); |
|
| 98 | + } else { |
|
| 99 | + digitalWrite(MOTOR1_CTRL_PIN, LOW); |
|
| 100 | + } |
|
| 101 | +} |
|
| 102 | + |
|
| 103 | +// Function to stop Motor 1 (active stop by 50% duty cycle on MOTOR1_CTRL_PIN) |
|
| 104 | +void stopMotor1() { |
|
| 105 | + analogWrite(MOTOR1_CTRL_PIN, PWM_STOP); |
|
| 106 | +} |
|
| 107 | + |
|
| 108 | +// Function to "brake" Motor 1. Performs an active stop. |
|
| 109 | +void brakeMotor1() { |
|
| 110 | + stopMotor1(); |
|
| 111 | +} |
|
| 112 | + |
|
| 113 | +// --- Motor 2 Control Functions --- |
|
| 114 | +// Function to drive Motor 2 with digital control for direction |
|
| 115 | +// forward: true for forward (MOTOR2_CTRL_PIN HIGH), false for reverse (MOTOR2_CTRL_PIN LOW) |
|
| 116 | +void driveMotor2(bool forward) { |
|
| 117 | + if (forward) { |
|
| 118 | + digitalWrite(MOTOR2_CTRL_PIN, HIGH); |
|
| 119 | + } else { |
|
| 120 | + digitalWrite(MOTOR2_CTRL_PIN, LOW); |
|
| 121 | + } |
|
| 122 | +} |
|
| 123 | + |
|
| 124 | +// Function to stop Motor 2 |
|
| 125 | +void stopMotor2() { |
|
| 126 | + // Try a different PWM value if 50% doesn't work |
|
| 127 | + analogWrite(MOTOR2_CTRL_PIN, PWM_STOP); // or try PWM_MAX |
|
| 128 | + // Alternatively, try digitalWrite |
|
| 129 | + // digitalWrite(MOTOR2_CTRL_PIN, LOW); // or try HIGH |
|
| 130 | +} |
|
| 131 | + |
|
| 132 | +// Function to "brake" Motor 2. Performs an active stop. |
|
| 133 | +void brakeMotor2() { |
|
| 134 | + stopMotor2(); |
|
| 135 | +} |
|
| 136 | +// --- END: Motor control functions from drv8871-rc.ino --- |
|
| 137 | + |
|
| 138 | +// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255) |
|
| 139 | +// with a deadband around the center (e.g., 50). |
|
| 140 | +long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) { |
|
| 141 | + long mappedValue = 0; |
|
| 142 | + int deadbandLower = rcCenter - deadbandRadius; |
|
| 143 | + int deadbandUpper = rcCenter + deadbandRadius; |
|
| 144 | + |
|
| 145 | + if (rcValue < deadbandLower) { |
|
| 146 | + // Map the range [rcMin, deadbandLower - 1] to [outMin, -1] |
|
| 147 | + // Ensure deadbandLower - 1 is not less than rcMin |
|
| 148 | + if (deadbandLower -1 < rcMin) { |
|
| 149 | + mappedValue = outMin; |
|
| 150 | + } else { |
|
| 151 | + mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1); |
|
| 152 | + } |
|
| 153 | + } else if (rcValue > deadbandUpper) { |
|
| 154 | + // Map the range [deadbandUpper + 1, rcMax] to [1, outMax] |
|
| 155 | + // Ensure deadbandUpper + 1 is not greater than rcMax |
|
| 156 | + if (deadbandUpper + 1 > rcMax) { |
|
| 157 | + mappedValue = outMax; |
|
| 158 | + } else { |
|
| 159 | + mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax); |
|
| 160 | + } |
|
| 161 | + } else { |
|
| 162 | + // Inside deadband |
|
| 163 | + mappedValue = 0; |
|
| 164 | + } |
|
| 165 | + return constrain(mappedValue, outMin, outMax); |
|
| 166 | +} |
|
| 167 | + |
|
| 168 | +// Function to create a random blinking effect for WS2812 LEDs |
|
| 169 | +void randomBlinkEffect() { |
|
| 170 | + for (int i = 0; i < LED_COUNT; i++) { |
|
| 171 | + // Turn on a random LED with a random color |
|
| 172 | + if (random(0, 2) == 1) { // 50% chance to turn on this LED |
|
| 173 | + strip.setPixelColor(i, strip.Color(random(0, 256), random(0, 256), random(0, 256))); |
|
| 174 | + } else { |
|
| 175 | + strip.setPixelColor(i, strip.Color(0, 0, 0)); // Turn off |
|
| 176 | + } |
|
| 177 | + } |
|
| 178 | + strip.show(); // Send the updated pixel colors to the hardware. |
|
| 179 | + delay(100); // Wait a short period |
|
| 180 | +} |
|
| 181 | + |
|
| 182 | +void loop() { |
|
| 183 | + // Read mapped control signals from each channel |
|
| 184 | + aileronControl = readAileronControlSignal(); // Throttle (0-100) |
|
| 185 | + elevatorControl = readElevatorControlSignal(); // Steering (0-100) |
|
| 186 | + |
|
| 187 | + // Print the mapped control signal values to the Serial Monitor |
|
| 188 | + Serial.print("Aileron (Throttle): "); |
|
| 189 | + Serial.print(aileronControl); |
|
| 190 | + Serial.print(" Elevator (Steering): "); |
|
| 191 | + Serial.print(elevatorControl); |
|
| 192 | + // Serial.println(); // Combined with next print |
|
| 193 | + |
|
| 194 | + // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input) |
|
| 195 | + // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0. |
|
| 196 | + int deadbandRadius = 15; |
|
| 197 | + // Factors to adjust how throttle and steering mix. |
|
| 198 | + // With on/off control, these primarily affect the outcome when throttle and steering have opposing commands. |
|
| 199 | + float steeringFactor = 1.0; // Start with 1.0, adjust if needed |
|
| 200 | + float throttleFactor = 1.0; // Start with 1.0, adjust if needed |
|
| 201 | + |
|
| 202 | + // Map control values with deadband. Output is -255 to 255, or 0 if in deadband. |
|
| 203 | + long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255); |
|
| 204 | + long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255); |
|
| 205 | + |
|
| 206 | + // Apply sensitivity factors |
|
| 207 | + long throttleValue = rawThrottleValue * throttleFactor; |
|
| 208 | + long adjustedSteeringValue = rawSteeringValue * steeringFactor; |
|
| 209 | + |
|
| 210 | + // Mix throttle and steering for differential drive |
|
| 211 | + // The magnitude of these values will only determine the sign for direction control. |
|
| 212 | + long motor1MixedOutput = throttleValue + adjustedSteeringValue; |
|
| 213 | + long motor2MixedOutput = throttleValue - adjustedSteeringValue; |
|
| 214 | + |
|
| 215 | + // Print mixed output for debugging |
|
| 216 | + Serial.print(" M1_Mix: "); |
|
| 217 | + Serial.print(motor1MixedOutput); |
|
| 218 | + Serial.print(" M2_Mix: "); |
|
| 219 | + Serial.print(motor2MixedOutput); |
|
| 220 | + Serial.println(); |
|
| 221 | + |
|
| 222 | + |
|
| 223 | + // --- START: Motor control logic using drv8871 functions --- |
|
| 224 | + // Motor 1 Control |
|
| 225 | + if (motor1MixedOutput > 0) { // Any positive value means forward |
|
| 226 | + driveMotor1(true); |
|
| 227 | + } else if (motor1MixedOutput < 0) { // Any negative value means reverse |
|
| 228 | + driveMotor1(false); |
|
| 229 | + } else { // Zero means stop |
|
| 230 | + stopMotor1(); |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + // Motor 2 Control |
|
| 234 | + if (motor2MixedOutput > 0) { // Any positive value means forward |
|
| 235 | + driveMotor2(true); |
|
| 236 | + } else if (motor2MixedOutput < 0) { // Any negative value means reverse |
|
| 237 | + driveMotor2(false); |
|
| 238 | + } else { // Zero means stop |
|
| 239 | + stopMotor2(); |
|
| 240 | + } |
|
| 241 | + // --- END: Motor control logic using drv8871 functions --- |
|
| 242 | + |
|
| 243 | + // Add the LED effect |
|
| 244 | + randomBlinkEffect(); // This function contains a delay(100) |
|
| 245 | + |
|
| 246 | + delay(20); // Delay for RC input reading cycle. Total loop delay is this + randomBlinkEffect delay. |
|
| 247 | + |
|
| 248 | + // At the end of your loop |
|
| 249 | + Serial.print("Motor2 Output: "); |
|
| 250 | + if (motor2MixedOutput > 0) { |
|
| 251 | + Serial.println("FORWARD"); |
|
| 252 | + } else if (motor2MixedOutput < 0) { |
|
| 253 | + Serial.println("REVERSE"); |
|
| 254 | + } else { |
|
| 255 | + Serial.println("STOP COMMANDED"); |
|
| 256 | + } |
|
| 257 | +} |
|
| ... | ... | \ No newline at end of file |
board-3rd-dat/nodemcu-dat/nodemcu-dat.md
| ... | ... | @@ -32,6 +32,8 @@ |
| 32 | 32 | | | 3.3V | | | |
| 33 | 33 | |
| 34 | 34 | |
| 35 | +- [[ESP8266-dat]] |
|
| 36 | + |
|
| 35 | 37 | ## Boards |
| 36 | 38 | |
| 37 | 39 | - [[NWI1044-dat]] |