Mailbag #36
Well after the shocking reviews for my last two videos I've decided to do the old favourite - a mailbag!
Algorithm alone knows these are so popular, but as I'm behind on opening up my late night purchases I'd better get to it!
The only extra bit is the code I had to write for the two joystick Arduino module - I couldn't find anything online and so I cobbled together the following - which works fine.
/* * Found this twin joystick module online here: * https://www.aliexpress.com/item/1005001882246352.html * * ..but with no code I had to find out the pins for * input and output, then made the code below to demonstrate * the use of the module - enjoy! * * Exponential function provided by BARD * https://bard.google.com/ * * OneCircuit - https://www.youtube.com/@onecircuit-as * Tue 26 Dec 2023 16:28:52 AEDT */ #define LjoyXaxis_pin A0 #define LjoyYaxis_pin A1 #define RjoyXaxis_pin A3 #define RjoyYaxis_pin A2 #define LSW_pin 2 #define RSW_pin 4 #define LLEDPin 9 #define RLEDPin 10 int LYLED = 0; int RYLED = 0; boolean LButton = 0; boolean RButton = 0; int exponentialMap(int S) { float base = 3.0; float normalizedS = S / 1023.0; float L = pow(normalizedS, base) * 255.0; return constrain(L, 0, 255); } void setup() { pinMode(LjoyXaxis_pin, INPUT); pinMode(LjoyYaxis_pin, INPUT); pinMode(RjoyXaxis_pin, INPUT); pinMode(RjoyYaxis_pin, INPUT); pinMode(LSW_pin, INPUT); pinMode(RSW_pin, INPUT); pinMode(LLEDPin, OUTPUT); pinMode(RLEDPin, OUTPUT); digitalWrite(LSW_pin, HIGH); digitalWrite(RSW_pin, HIGH); Serial.begin(115200); } void loop() {
// Left joystick routines
Serial.print("LX-axis:"); Serial.print(analogRead(LjoyXaxis_pin)); Serial.print(":"); LButton = 1 - digitalRead(LSW_pin); LYLED = 1023 - analogRead(LjoyYaxis_pin); Serial.print("LY-axis:"); Serial.print(LYLED); Serial.print(":"); if (LButton == 0) { // LYLED = map(LYLED, 0, 1023, 0, 255); // linear map // LYLED = pow(1.0054,LYLED); // exponential map LYLED = exponentialMap(LYLED); analogWrite(LLEDPin, LYLED); } else { analogWrite(LLEDPin, 0); } Serial.print("LSW:"); Serial.print(LButton);
// Right joystick routines
Serial.print(" RX-axis:"); Serial.print(analogRead(RjoyXaxis_pin)); Serial.print(":"); RButton = 1 - digitalRead(RSW_pin); RYLED = 1023 - analogRead(RjoyYaxis_pin); Serial.print("RY-axis:"); Serial.print(RYLED); Serial.print(":"); if (RButton == 0) { // RYLED = map(RYLED, 0, 1023, 0, 255); // linear map // RYLED = pow(1.0054,RYLED); // exponential map RYLED = exponentialMap(RYLED); analogWrite(RLEDPin, RYLED); } else { analogWrite(RLEDPin, 0); } Serial.print("RSW:"); Serial.println(RButton);
delay(100);
}
Thank you to BARD for the exponential mapping function - increase "float base = 3.0;" for a flatter curve.
User: Can you suggest an Arduino function that maps
numbers 0-1023 (S: from a joystick source)
to 0-255 (L: for an LED output), but instead of
mapping linearly it maps exponentially so that
values of S such as 300 map quite low to, for
instance, to an L value of 5, and a value of
L=600 maps to, for instance, S=25? Bard: Here's an Arduino function that maps
numbers 0-1023 to 0-255 exponentially,
as you described: Arduino int exponentialMap(int S) { // Adjust this base value to fine-tune the curve float base = 2.0; // Normalize S to a range of 0.0 to 1.0 float normalizedS = S / 1023.0; // Apply exponential curve using pow() function float L = pow(normalizedS, base) * 255.0; // Clamp L to 0-255 range to ensure valid output return constrain(L, 0, 255); } Use code with caution. Learn more Explanation: Normalization: The normalizedS calculation ensures
the input value S is within a 0.0 to 1.0 range,
making it suitable for exponential calculations.
Exponential Mapping: The pow(normalizedS, base)
expression applies the exponential curve. The base
variable controls the steepness of the curve: Higher base values result in a more pronounced
exponential response.
Lower base values lead to a more gradual curve.
Scaling: The result of pow() is multiplied
by 255.0 to scale it back to the 0-255 range
for LED output. Clamping: The constrain(L, 0, 255) function
ensures the final output value L stays within
the valid 0-255 range, even if the calculation
produces a value outside this range. Usage: Arduino int S = analogRead(joystickPin); // Read joystick value int L = exponentialMap(S); // Apply exponential mapping analogWrite(ledPin, L); // Set LED brightness Use code with caution. Learn more Customization: Experiment with different base values to achieve
the desired mapping curve.
Consider adjusting the normalization and scaling
factors if your input or output ranges differ. User: Works beautifully - well done! 👏👏👏 Bard: I'm glad it works well for you! Thank you for
the appreciation, it makes helping fun! If you
have any other questions or challenges related
to Arduino or code, feel free to ask. I'm always
happy to assist.
And here is the video - enjoy!