Notifications
Clear all

KY-o40 - What nobody bothers to mention!

8 Posts
2 Users
1 Likes
2,203 Views
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

The KY-040 has been covered by lots of people on YouTube, even by Bill.

What all of them have forgotten to mention is the middle pin labelled "SW" and how it works. This is a momentary switch that does not work as I expected it too! I expected the pin to go HIGH if the switch was pressed, silly me!

I connected this pin directly to a pin on the Arduino and changed the sketch to monitor the pin's state and got some strange results. So I attached my oscilloscope to the "SW" and when not pressed I was getting a ripple at 0V and when the switch was pressed the 0V ripple disappears. Conclusion: when the switch is not pressed then the pin is floating and when pressed the "SW" pin is providing a route to GND.

I have confirmed this by attaching an LED with a resistor to the 5V pin then to "SW" pin. Now when pressed the LED lights up. My guess is that an Arduino pin needs a pullup resistor and will be pulled LOW when the switch is pressed.


   
Quote
Topic Tags
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

Eric


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

And here is the version playing with a small SG90 micro-servo (trying to attach the source file, i'll edit if it doesn't work)

 

Eric


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@zeferby

Here is a modified DBW example i edited from Bill's, with encoder switch detection (implementing a "Return to Zero") and "high speed" encoder rotation detection, with 5 leds and the encoder switch pulled high : check the #defines at the beginning of the sketch for the pin numbers !!

Thanks for sharing!

Tried it out and works well, I am sure I will glean some info from the code regarding coding the switch.

What I am trying to achieve is the following:

I wish to be able to toggle the Arduino between "learning" and "operation" modes.

The learning mode would involve moving a servo or stepper motor to a particular position with the rotary decoder, and then storing the position in the EEPROM using the momentary switch.

The operation mode involves automatically moving the servo/stepper to the stored positions, ad infinitum or until I change the stored values. 


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@pugwash I see, something like an adjustable "homing" position.

I suppose you're aware of Flash/EEPROM wear ? I have been reading on PROGMEM after looking at some library source files, which led me to look at the EEPROM capacities...what i read did not encourage me to use the Arduino's own EEPROM but rather to add an external chip (that can be replaced when wear level gets too high) for EEPROM storage.  Of course that depends on the expected frequency of write/erase operations...

While browsing i found this repo, and especially the Atmel doc linked there, that you may be interested in :

https://github.com/drjoju/Arduino-wear-leveling

Eric


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

@zeferby

Thanks for drawing my attention to this issue, but I have also read about EEPROM wear and that 10000 write/erase cycles will wear out the EEPROM registers.

I am not particularly worried about this as the number of changes to be made to the registers will be nowhere near this limit, and considering the limited number of years I have left on this planet. ? 

And of course, if you wear out a number registers, you can change the starting address, if the number of registers needed does not exceed 512.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

Many thanks to @zeferby

The following is the bare minimum code to poll the rotary encoder switch.

#define inputSW 6 //attach  UNO pin D6 to SW pin on rotary encoder
// const byte interruptPin = 2; // alternative to pin 6

#define ledZero 10 //attach to an LED on UNO pin D10

void setup() {
pinMode (inputSW,INPUT_PULLUP);
// pinMode (interruptPin,INPUT_PULLUP);
// attachInterrupt(digitalPinToInterrupt(interruptPin), doSomething, FALLING);
}

void loop() {
int currentStateSW = digitalRead(inputSW);

if(currentStateSW == LOW){
digitalWrite(ledZero, HIGH); // the do something part
}
else{
digitalWrite(ledZero, LOW);
}
void doSomething(){
// another do something section
}
}

In a large program, it would probably be advisable to attach the switch SW to an interrupt pin (2 or 3), looking for a falling signal as the alternative commented out code above shows.

 


   
ZeFerby reacted
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
Topic starter  

Corrected an obvious mistake! ? 

#define inputSW 6 //attach UNO pin D6 to SW pin on rotary encoder
// const byte interruptPin = 2; // alternative to pin 6

#define ledZero 10 //attach to an LED on UNO pin D10

void setup() {
pinMode (inputSW,INPUT_PULLUP);
// pinMode (interruptPin,INPUT_PULLUP);
// attachInterrupt(digitalPinToInterrupt(interruptPin), doSomething, FALLING);
}

void loop() {
int currentStateSW = digitalRead(inputSW);

if(currentStateSW == LOW){
digitalWrite(ledZero, HIGH); // the do something part
}else{
digitalWrite(ledZero, LOW);
}
}

void doSomething(){
// another do something section
}

   
ReplyQuote