Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Post Reply
maniac
Posts: 9
Joined: Tue Mar 23, 2021 5:52 pm

Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by maniac » Fri Apr 09, 2021 8:31 am

Hi,

I would like to ask colleagues with more experience for their opinion.

I am at the stage of reading the value of the analogue pads in micropython on the micro: bit platform.

Can this code be shortened? I want to determine and save (for later use) in this code the zero position of the joystick, and the max. And min. Positions. for each axis in order to correctly position the servo in the program on the basis of the established ranges.

How do I map the known ranges of deflection for the full range of the servo deflection? There is some function in micropythona. I note that I haven't been looking yet. So far I have struggled with this program.

Thanks to everyone for any suggestions and help. If I use bad programming practices somewhere, please write. Man learns from mistakes 🙂

"print" and "sleep" lines in ext. they are only for checking what I have in the variables.

Code: Select all

from microbit import *

max_x = 0
max_y = 0
min_y = 0
min_x = 0
zero_y = int(pin0.read_analog())
zero_x = int(pin1.read_analog())

while True:
    click = pin2.read_digital()
    while not(click):

        value = pin0.read_analog()

        while value > zero_y and value > max_y:
            max_y = value
            print(str(max_y))
            sleep(100)
            min_y = max_y/2

        while value < zero_y and value < min_y:
            min_y = value
            print(str(min_y))
            sleep(100)
        
        value = pin1.read_analog()
        
        while value > zero_x and value > max_x:
            max_x = value
            print(str(max_x))
            sleep(100)
            min_x = max_x/2

        while value < zero_x and value < min_x:
            min_x = value
            print(str(min_x))
            sleep(100)
        click = pin2.read_digital()
    break

print('min x: '+str(min_x)+' max x: '+str(max_x))
print('min y: '+str(min_y)+' max y: '+str(max_y))
print('zero x: '+str(zero_x)+' zero y: '+str(zero_y))
sleep(100)


scruss
Posts: 79
Joined: Sat Aug 12, 2017 2:27 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by scruss » Fri Apr 09, 2021 1:20 pm

So, an analogue (potentiometer) joystick with the y-axis on pin0 and the x-axis on pin1? If I understand the micro:bit's MicroBitPin class right, you're going to get a full range of 0 – 1023 from a read_analog() call.

Will you be using this one joystick, or are you writing code that could be used with any joystick? For a generic analogue joystick with no other resistors in the chain, you're going to get pretty close to 0 at one end of the range, and pretty close to 1023 at the other. So you could remove the whole calibration routine and assume any value < 32 (say) is zero, and any value > 991 is full deflection the other way.

Try this in the REPL: hold the joystick at min or max y position, and then do pin0.read_analog(). It should be near 0 or 1023.

For converting the ranges from joystick input to servo output, there's no built-in function. Take a look at the map function thread for some code that should help.

The other thing about analogue joysticks is that they're noisy. If you take the readings from the joystick and directly map them to servo positions, your servos will very likely twitch and jitter. You can smooth this a bit by averaging multiple readings. If your joystick automatically centres, it can help to program in a dead band, where (for instance) readings from 480 – 543 are all mapped to 50% deflection. This will keep your servos calm while you're not using the joystick, but will allow them to move when the joystick's off centre.

maniac
Posts: 9
Joined: Tue Mar 23, 2021 5:52 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by maniac » Sat Apr 10, 2021 7:40 am

Hi,

Yes. I would like to use the code as a function for various joysticks used in my projects.
With its help, I want to define the full range of values ​​given to the microcontroller, any connected joystick.
The Y axis of the joystick is wired to pin0 and the X axis is wired to pin1. The joystick button is connected to pin2.
Becouse the code is to be used as a function, I would like it to be as small and simple as possible.
Could it be simplified further in your opinion?
Thanks for the link to value mapping.

maniac
Posts: 9
Joined: Tue Mar 23, 2021 5:52 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by maniac » Sat Apr 10, 2021 7:42 am

The joystick I am using now for testing has a range of 4 - 1023 on both axes.

maniac
Posts: 9
Joined: Tue Mar 23, 2021 5:52 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by maniac » Sat Apr 10, 2021 8:43 am

What do you mean they are noisy?

maniac
Posts: 9
Joined: Tue Mar 23, 2021 5:52 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by maniac » Sat Apr 10, 2021 5:33 pm

Thanks to colleague deshipu's suggestions on another forum, I was able to shorten the code to a satisfactory level.
By the way, it came in handy when I changed the voltage from 3.3V to 5V for the servo. I forgot about it and connected the joystick. The X and Y ranges as well as the neutral position were very low (~ 25%). The program picked up the ranges correctly in relation to the current value of the voltage with which I powered the joystick. So a program in which I use the function would work fine. And for such occasions, I need this feature. The program will start with the correct ranges, even if I change the joystick or change the voltage. I won't have to worry about it :)

Now I would like to write code where I would get the full range of serv values ​​without limit switches.
Then I will map this data. Is it possible at all?

Below is the final code.

Code: Select all


from microbit import *

min_x = max_x = zero_x = int(pin1.read_analog())
min_y = max_y = zero_y = int(pin0.read_analog())

while True:
    while not pin2.read_digital():

        value = pin0.read_analog()

        if value > max_y:
            max_y = value
        elif value < min_y:
            min_y = value
         
        value = pin1.read_analog()

        if value > max_x:
            max_x = value
        elif value < min_x:
            min_x = value
            
    break

print('min x: %s  max x: %s ' % (min_x, max_x))
print('min y: %s  max y: %s ' % (min_y, max_y))
print('zero x: %s  zero y: %s' % (zero_x, zero_y))
sleep(100)


scruss
Posts: 79
Joined: Sat Aug 12, 2017 2:27 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by scruss » Sat Apr 10, 2021 6:19 pm

maniac wrote: ↑
Sat Apr 10, 2021 8:43 am
What do you mean they are noisy?
potentiometer_noise.png
raw potentiometer readings showing noise
potentiometer_noise.png (6.66 KiB) Viewed 1118 times
That graph is a series of readings from a potentiometer sitting at its centre position, scaled to the same 0 … 1023 range that you are using. It's reading between 509 and 517, but the device isn't moving at all. It's just something analogue devices do.

This noise would result in your servo jittering ±1° all the time if you mapped the joystick input directly to the output. Maybe you can live with that. I'd find it annoying, though.

maniac
Posts: 9
Joined: Tue Mar 23, 2021 5:52 pm

Re: Program that reads max. min. analog is raining. Micropython micro: bit How to optimize this code?

Post by maniac » Sun Apr 11, 2021 6:41 pm

Ok. Now I understand what's going on. Thanks for the clarification.

Post Reply