21841d25835452aa9c54b9ff3b4b0a743505d0ae
Board-dat/Board-DAT.md
| ... | ... | @@ -174,6 +174,8 @@ LED control - [[ILC1063-dat]] |
| 174 | 174 | [[ACDC-dat]] |
| 175 | 175 | - [[OPM1178-dat]] - [[OPM1110-dat]] - [[OPM1111-dat]] - [[OPM1065-dat]] - [[OPM1114-dat]] |
| 176 | 176 | |
| 177 | +- [[OPM1068-dat]] |
|
| 178 | + |
|
| 177 | 179 | battery holder - [[OPM1189-dat]] |
| 178 | 180 | |
| 179 | 181 | battery drainer - [[OPM1133-dat]] - [[OPM1134-dat]] |
Board-dat/OPM/OPM1068-dat/OPM1068-dat.md
| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | + |
|
| 2 | +# OPM1068-dat |
|
| 3 | + |
|
| 4 | +Protection: |
|
| 5 | + |
|
| 6 | +- overload |
|
| 7 | +- short circuit - [[SCP-dat]] |
|
| 8 | +- overheat |
|
| 9 | +- over-current protection. |
|
| 10 | + |
|
| 11 | +Board will lock and recover when turn it on/off. - [[protection-dat]] |
|
| ... | ... | \ No newline at end of file |
Chip-dat/morsun-dat/B-S-1W-dat/B-S-1W-dat.md
| ... | ... | @@ -40,7 +40,7 @@ datasheet |
| 40 | 40 | |
| 41 | 41 | **Inside Circuitry**: Although I didn’t get a worthy chance to break apart the B0505S-1W module, it came to my notice that its inside electronics is mainly based on the “Royer Oscillator” (https://en.wikipedia.org/wiki/Royer_oscillator) circuit. |
| 42 | 42 | |
| 43 | -As far as I know, the traditional Royer oscillator circuit only provides basic functions but once the circuit is abnormal, the module may be damaged and even cause serious consequences. **At present, the module is available without a continuous short circuit protection (SCP) feature!** |
|
| 43 | +As far as I know, the traditional Royer oscillator circuit only provides basic functions but once the circuit is abnormal, the module may be damaged and even cause serious consequences. **At present, the module is available without a continuous short circuit protection (SCP) feature!** - [[SCP-dat]] - [[protection-dat]] |
|
| 44 | 44 | |
| 45 | 45 | [read more on this post. - MORNSUN® B0505S-1W Review](https://www.codrey.com/electronic-circuits/mornsun-b0505s-1w-review/) |
| 46 | 46 |
Tech-dat/protection-dat/protection-dat.md
| ... | ... | @@ -5,6 +5,19 @@ |
| 5 | 5 | |
| 6 | 6 | - [[USB-ESD-dat]] |
| 7 | 7 | |
| 8 | +## Power Protection |
|
| 9 | + |
|
| 10 | +- overload |
|
| 11 | +- short circuit - [[SCP-protection-dat]] |
|
| 12 | + |
|
| 13 | +- over-current protection. - [[OCP-protection-dat]] |
|
| 14 | +- over-temperature protection == overheat - [[OTP-protection-dat]] |
|
| 15 | +- over-voltage protection - [[OVP-protection-dat]] |
|
| 16 | + |
|
| 17 | + |
|
| 18 | +## board |
|
| 19 | + |
|
| 20 | +- [[B-S-1W-dat]] |
|
| 8 | 21 | |
| 9 | 22 | ## ref |
| 10 | 23 |
app-dat/RC-dat/RC-code-dat/rover-2.ino
| ... | ... | @@ -0,0 +1,170 @@ |
| 1 | +#include <Adafruit_NeoPixel.h> |
|
| 2 | + |
|
| 3 | +// Define pins for each RC channel |
|
| 4 | +int aileronPin = 14; // Channel 1 (Throttle) |
|
| 5 | +int elevatorPin = 12; // Channel 2 (Steering) |
|
| 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 |
|
| 12 | + |
|
| 13 | +// WS2812 LED Strip Configuration |
|
| 14 | +#define LED_PIN 15 |
|
| 15 | +#define LED_COUNT 8 |
|
| 16 | +Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); |
|
| 17 | + |
|
| 18 | +long aileronControl; // Mapped value from aileron channel (0-100) |
|
| 19 | +long elevatorControl; // Mapped value from elevator channel (0-100) |
|
| 20 | + |
|
| 21 | +// Reads the PWM signal from the aileron channel and maps it to 0-100 |
|
| 22 | +long readAileronControlSignal() { |
|
| 23 | + unsigned long rawPWM = pulseIn(aileronPin, HIGH, 25000); |
|
| 24 | + // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50) |
|
| 25 | + // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid. |
|
| 26 | + if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) { |
|
| 27 | + return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 28 | + } |
|
| 29 | + // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 30 | + long constrainedPWM = constrain(rawPWM, 1000, 2000); |
|
| 31 | + return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 32 | +} |
|
| 33 | + |
|
| 34 | +// Reads the PWM signal from the elevator channel and maps it to 0-100 |
|
| 35 | +long readElevatorControlSignal() { |
|
| 36 | + unsigned long rawPWM = pulseIn(elevatorPin, HIGH, 25000); |
|
| 37 | + // If signal is lost (timeout) or clearly out of valid RC pulse range, return neutral (50) |
|
| 38 | + // Valid RC pulses are typically 1000-2000us. Values outside ~900-2100us are treated as invalid. |
|
| 39 | + if (rawPWM == 0 || rawPWM < 900 || rawPWM > 2100) { |
|
| 40 | + return 50; // Mid-point for 0-100 scale (1500us equivalent), results in stop |
|
| 41 | + } |
|
| 42 | + // Otherwise, the signal is likely valid; constrain it to the standard 1000-2000us range and map |
|
| 43 | + long constrainedPWM = constrain(rawPWM, 1000, 2000); |
|
| 44 | + return map(constrainedPWM, 1000, 2000, 0, 100); |
|
| 45 | +} |
|
| 46 | + |
|
| 47 | +void setup() { |
|
| 48 | + pinMode(aileronPin, INPUT); |
|
| 49 | + pinMode(elevatorPin, INPUT); // Initialize elevator pin |
|
| 50 | + |
|
| 51 | + pinMode(ENA, OUTPUT); |
|
| 52 | + pinMode(ENB, OUTPUT); |
|
| 53 | + pinMode(IN1, OUTPUT); |
|
| 54 | + pinMode(IN2, OUTPUT); |
|
| 55 | + |
|
| 56 | + // Initialize motors to off |
|
| 57 | + digitalWrite(IN1, LOW); |
|
| 58 | + digitalWrite(IN2, LOW); |
|
| 59 | + analogWrite(ENA, 0); |
|
| 60 | + analogWrite(ENB, 0); |
|
| 61 | + |
|
| 62 | + Serial.begin(9600); |
|
| 63 | + |
|
| 64 | + strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) |
|
| 65 | + strip.show(); // Turn OFF all pixels ASAP |
|
| 66 | + strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) |
|
| 67 | +} |
|
| 68 | + |
|
| 69 | +// Helper function to control a single motor |
|
| 70 | +// pwmVal: -255 (full backward) to 255 (full forward) |
|
| 71 | +void setMotorOutput(int dirPin, int speedPin, int pwmVal) { |
|
| 72 | + if (pwmVal > 0) { // Forward |
|
| 73 | + digitalWrite(dirPin, HIGH); |
|
| 74 | + analogWrite(speedPin, pwmVal); |
|
| 75 | + } else if (pwmVal < 0) { // Backward |
|
| 76 | + digitalWrite(dirPin, LOW); |
|
| 77 | + analogWrite(speedPin, -pwmVal); // Speed is positive |
|
| 78 | + } else { // Stop |
|
| 79 | + digitalWrite(dirPin, LOW); // Or HIGH, doesn't matter much if speed is 0 |
|
| 80 | + analogWrite(speedPin, 0); |
|
| 81 | + } |
|
| 82 | +} |
|
| 83 | + |
|
| 84 | +// Helper function to map RC control input (0-100) to an output range (e.g., -255 to 255) |
|
| 85 | +// with a deadband around the center (e.g., 50). |
|
| 86 | +long mapWithDeadband(long rcValue, int rcMin, int rcMax, int rcCenter, int deadbandRadius, int outMin, int outMax) { |
|
| 87 | + long mappedValue = 0; |
|
| 88 | + int deadbandLower = rcCenter - deadbandRadius; |
|
| 89 | + int deadbandUpper = rcCenter + deadbandRadius; |
|
| 90 | + |
|
| 91 | + if (rcValue < deadbandLower) { |
|
| 92 | + // Map the range [rcMin, deadbandLower - 1] to [outMin, -1] |
|
| 93 | + // Ensure deadbandLower - 1 is not less than rcMin |
|
| 94 | + if (deadbandLower -1 < rcMin) { |
|
| 95 | + mappedValue = outMin; |
|
| 96 | + } else { |
|
| 97 | + mappedValue = map(rcValue, rcMin, deadbandLower - 1, outMin, -1); |
|
| 98 | + } |
|
| 99 | + } else if (rcValue > deadbandUpper) { |
|
| 100 | + // Map the range [deadbandUpper + 1, rcMax] to [1, outMax] |
|
| 101 | + // Ensure deadbandUpper + 1 is not greater than rcMax |
|
| 102 | + if (deadbandUpper + 1 > rcMax) { |
|
| 103 | + mappedValue = outMax; |
|
| 104 | + } else { |
|
| 105 | + mappedValue = map(rcValue, deadbandUpper + 1, rcMax, 1, outMax); |
|
| 106 | + } |
|
| 107 | + } else { |
|
| 108 | + // Inside deadband |
|
| 109 | + mappedValue = 0; |
|
| 110 | + } |
|
| 111 | + return constrain(mappedValue, outMin, outMax); |
|
| 112 | +} |
|
| 113 | + |
|
| 114 | +// Function to create a random blinking effect for WS2812 LEDs |
|
| 115 | +void randomBlinkEffect() { |
|
| 116 | + for (int i = 0; i < LED_COUNT; i++) { |
|
| 117 | + // Turn on a random LED with a random color |
|
| 118 | + if (random(0, 2) == 1) { // 50% chance to turn on this LED |
|
| 119 | + strip.setPixelColor(i, strip.Color(random(0, 256), random(0, 256), random(0, 256))); |
|
| 120 | + } else { |
|
| 121 | + strip.setPixelColor(i, strip.Color(0, 0, 0)); // Turn off |
|
| 122 | + } |
|
| 123 | + } |
|
| 124 | + strip.show(); // Send the updated pixel colors to the hardware. |
|
| 125 | + delay(100); // Wait a short period |
|
| 126 | +} |
|
| 127 | + |
|
| 128 | +void loop() { |
|
| 129 | + // Read mapped control signals from each channel |
|
| 130 | + aileronControl = readAileronControlSignal(); // Throttle (0-100) |
|
| 131 | + elevatorControl = readElevatorControlSignal(); // Steering (0-100) |
|
| 132 | + |
|
| 133 | + // Print the mapped control signal values to the Serial Monitor |
|
| 134 | + Serial.print("Aileron (Throttle): "); |
|
| 135 | + Serial.print(aileronControl); |
|
| 136 | + Serial.print(" Elevator (Steering): "); |
|
| 137 | + Serial.print(elevatorControl); |
|
| 138 | + Serial.println(); |
|
| 139 | + |
|
| 140 | + // Define deadband radius (e.g., +/- 5 around center of 50 for a 0-100 input) |
|
| 141 | + // This means input values from 45 to 55 (inclusive if center is 50 and radius is 5) will be treated as 0. |
|
| 142 | + int deadbandRadius = 15; |
|
| 143 | + float steeringFactor = 3; // Adjust this value to change steering sensitivity |
|
| 144 | + float throttleFactor = 3; // Adjust this value to change throttle sensitivity (e.g., 1.2 for 20% stronger throttle) |
|
| 145 | + |
|
| 146 | + // Map control values with deadband |
|
| 147 | + long rawThrottleValue = mapWithDeadband(aileronControl, 0, 100, 50, deadbandRadius, -255, 255); |
|
| 148 | + long rawSteeringValue = mapWithDeadband(elevatorControl, 0, 100, 50, deadbandRadius, -255, 255); |
|
| 149 | + |
|
| 150 | + // Apply sensitivity factors |
|
| 151 | + long throttleValue = rawThrottleValue * throttleFactor; |
|
| 152 | + long adjustedSteeringValue = rawSteeringValue * steeringFactor; |
|
| 153 | + |
|
| 154 | + // Mix throttle and steering for differential drive |
|
| 155 | + long motor1Pwm = throttleValue + adjustedSteeringValue; |
|
| 156 | + long motor2Pwm = throttleValue - adjustedSteeringValue; |
|
| 157 | + |
|
| 158 | + // Constrain PWM values to the valid range [-255, 255] |
|
| 159 | + motor1Pwm = constrain(motor1Pwm, -255, 255); |
|
| 160 | + motor2Pwm = constrain(motor2Pwm, -255, 255); |
|
| 161 | + |
|
| 162 | + // Set motor speeds and directions |
|
| 163 | + setMotorOutput(IN1, ENA, motor1Pwm); // Motor 1 |
|
| 164 | + setMotorOutput(IN2, ENB, motor2Pwm); // Motor 2 |
|
| 165 | + |
|
| 166 | + // Add the LED effect |
|
| 167 | + randomBlinkEffect(); |
|
| 168 | + |
|
| 169 | + delay(20); // Shorter delay for better responsiveness |
|
| 170 | +} |
|
| ... | ... | \ No newline at end of file |