I'm a beginner using Arduino with a Teensy 3.2 board and programming it as a usb keyboard.
I have two 4 button membrane switches. Their button contacts are on pins 1-8, and the 9th pin holds a soldered together wire of both membrane switches' "ground" line or whatever it's true name is; the line that completes the circuit.
Basically when you press the buttons they are supposed to simply type "a, b, c..." respectively. I've been told I need to use a matrix for this.
I'm looking for an example of how to code a keyboard matrix that effectively supports a one row/9 column line (or vice versa?) I've been unable to find that solution online.
All I have so far is this code which, when the button on the second pin is pressed, sends tons of "AAAAAAAAAAAAAAAA" keystrokes.
void setup() {
// make pin 2 an input and turn on the
// pullup resistor so it goes high unless
// connected to ground:
pinMode(2, INPUT_PULLUP);
Keyboard.begin();
}
void loop() {
//if the button is pressed
if(digitalRead(2)==LOW){
//Send an ASCII 'A',
Keyboard.write(65);
}
}
Would anyone be able to help?
First of all, a 1-row keypad is NOT a matrix. Or better, technically it can be considered a matrix but... A matrix keypad is something like this:
You see? In order to scan this you have to
Pull Row1 to ground, while leaving rows 2-4 floating
Read the values of Col1-4. These are the values of switches 1-4
Pull Row2 to ground, while leaving rows 1 and 3-4 floating
Read the values of Col1-4. These are the values of switches 5-8
And so on, for all the rows
As for the other problem, you are printing an A when the button is held low. What you want to achieve is to print A only on the falling edge of the pin (ideally once per pressure), so
char currValue = digitalRead(2);
if((currValue==LOW) && (oldValue==HIGH))
{
//Send an ASCII 'A',
Keyboard.write(65);
}
oldValue = currValue;
Of course you need to declare oldValue outside the loop function and initialize it to HIGH in the main.
With this code you won't receive tons of 'A's, but however you will see something like 5-10 'A's every time you press the button. Why? Because of the bouncing of the button. That's what debouncing techniques are for!
I suggest you to look at the class Bounce2 to get an easy to use class for your button. IF you prefer some code, I wrote this small code for another question:
#define CHECK_EVERY_MS 20
#define MIN_STABLE_VALS 5
unsigned long previousMillis;
char stableVals;
char buttonPressed;
...
void loop() {
if ((millis() - previousMillis) > CHECK_EVERY_MS)
{
previousMillis += CHECK_EVERY_MS;
if (digitalRead(2) != buttonPressed)
{
stableVals++;
if (stableVals >= MIN_STABLE_VALS)
{
buttonPressed = !buttonPressed;
stableVals = 0;
if (buttonPressed)
{
//Send an ASCII 'A',
Keyboard.write(65);
}
}
}
else
stableVals = 0;
}
}
In this case there is no need to check for the previous value, since the function already has a point reached only when the state changes.
If you have to use this for more buttons, however, you will have to duplicate the whole code (and also to use more stableVals variables). That's why I suggsted you to use the Bounce2 class (it does something like this but, since it is all wrapped inside a class, you won't need to bother about variables).
Related
I'm quite new to Processing.
I'm trying to make Processing randomly play a video after I clear the screen by mouseclick, so I create an array that contain 3 videos and play one at a time.
Holding 'Spacebar' will play a video and release it will stop the video. Mouseclick will clear the screen to an image. The question is how can it randomize to another video if I press spacebar again after clear the screen.
I've been searching all over the internet but couldn't find any solution for my coding or if my logic is wrong, please help me.
Here's my code.
int value = 0;
PImage photo;
import processing.video.*;
int n = 3; //number of videos
float vidN = random(0, n+1);
int x = int (vidN);
Movie[] video = new Movie[3];
//int rand = 0;
int index = 0;
void setup() {
size(800, 500);
frameRate(30);
video = new Movie[3];
video[0] = new Movie (this, "01.mp4");
video[1] = new Movie (this, "02.mp4");
video[2] = new Movie (this, "03.mp4");
photo = loadImage("1.jpg");
}
void draw() {
}
void movieEvent(Movie video) {
video.read();
}
void keyPressed() {
if (key == ' ') {
image(video[x], 0, 0);
video[x].play();
}
}
void mouseClicked() {
if (value == 0) {
video[x].jump(0);
video[x].stop();
background(0);
image(photo, 0, 0);
}
}
You have this bit of logic in your code which picks a random integer:
float vidN = random(0, n+1);
int x = int (vidN);
In theory, if you want to randomise to another video when the spacebar is pressed again you can re-use this bit of logic:
void keyPressed() {
if (key == ' ') {
x = int(random(n+1));
image(video[x], 0, 0);
video[x].play();
}
}
(Above I've used shorthand of the two lines declaring vidN and x, but the logic is the same. If the logic is harder to follow since two operations on the same line (picking a random float between 0,n+1 and rounding down to an integer value), feel free to expand back to two lines: readability is more important).
As side notes, these bit of logic look a bit off:
the if (value == 0) condition will always be true since value never changes, making both value and the condition redundant. (Perhaps you plan to use for something else later ? If so, you could save separate sketches, but start with the simplest version and exclude anything you don't need, otherwise, in general, remove any bit of code you don't need. It will be easier to read, follow and change.)
Currently your logic says that whenever you click current video resets to the start and stops playing and when you hit the spacebar. Once you add the logic to randomise the video that the most recent frame of the current video (just randomised) will display (image(video[x], 0, 0);), then that video will play. Unless you click to stop the current video, previously started videos (via play()) will play in the background (e.g. if they have audio you'll hear them in the background even if you only see one static frame from the last time space was pressed).
Maybe this is the behaviour you want ? You've explained a localised section of what you want to achieve, but not overall what the whole of the program you posted should do. That would help others provide suggestions regarding logic.
In general, try to break the problem down to simple steps that you can test in isolation. Once you've found a solid solution for each part, you can add each part into a main sketch one at a time, testing each time you add something. (This way if something goes wrong it's easy to isolate/fix).
Kevin Workman's How To Program is a great article on this.
As a mental excercise it will help to read through the code line by line and imagine what it might do. Then run it and see if the code behaves as you predicted/intended. Slowly and surely this will get better and better. Have fun learning!
I'm new to Arduino, trying to make a random number generator with pushbutton.
My questions are:
How can I do that,if I press the pushbutton once, then I will get one random number between 0 and 1024. After that, I want to loop from 0 to the random number and then back to 0.
How can I debounce the pushbutton
Sample code:
void setup(){
Serial.begin(57600);
pinMode(2,INPUT_PULLUP);
attachInterrupt(0,randomnumber,FALLING);
}
void randomnumber(){
int number=random(0,1024);
for(int x=0;x<=number; x++){
Serial.println(x);
delay(1000);
}
for(int y=number;y>=0; y--){
Serial.println(y);
delay(1000);
}
}
void loop(){
}
Any good suggestion?
Ok, what you are looking for is "signal debouncing".
When you press the button, the signal does not go right from low to high value, but is noisy on onset(that's a general property of mechanical contacts), creating multiple "button presses". Common and working approach is:
1) button press detected(transition from 0 to 1 on your input pin)
2) delay(10) // wait for a few milliseconds
3) check the button again to see if it's still pressed; if true, the button was really pressed, if not then it was just some noise and can be ignored
This will reject any pulse shorter than 10 ms
Here is a short video describing what actually happens when you press the button: https://youtu.be/jYOYgU2vlSE
And an article along with code: https://programmingelectronics.com/tutorial-19-debouncing-a-button-with-arduino-old-version/
OK let me explain my problem.
I'm working on a program where I have a button. Clicking it causes the number "1" to appear, then, after that, any further clicks will increment that value until it reaches the value of "9". (It's a string). I wrote this code which declares an int variable to 0 (Yes, this was a mistake but let me continue) then increment it and parse it to string and show it on the button text(This is the code that executes on button click):
private: System::Void a0_Click(System::Object^ sender, System::EventArgs^ e) {
int i = 0;
i++;
a0->Text = i.ToString();
}
However, as you can suspect, I did the foolishness of declaring i with 0 for each button press, so the result was that 1 was the only value showing on the button. The next thing I tried doing, was declaring i as global variable with the value of 0. However, I came to another problem. I have 82 buttons of that kind, and I'm going for the easiest sollution I can find, so sharing the i variable seemed logical,
The next problem was that if I pressed 5 times the first button, the number displayed on it would be "5" however if I pressed another button, the value wouldn't be "1" by default, it would be "6" (The value of the first button incremented by one). Basically it would inherit the value of the first.
Now I'm at a dead end. I have no idea what to do. I tried using i and i2 but I was just chasing my own tail. Is there a very easy solution to this? Keep in mind I've got 82 buttons (Yes I know it's alot) which are by default 0. When I click each one I need it to increment by one, starting from 0. Any ideas?
Notes: OS is Windows XP, IDE is Visual Studio 2010m using windows forms app, C++/CLI. If I forgot to mention anything post in comments and I'll add it.
You can inspect sender to find out what button was clicked.
void anybutton_Click(System::Object^ sender, System::EventArgs^)
{
Button^ btn = dynamic_cast<Button^>(sender); // or safe_cast
int i;
if (System::Int32::TryParse(btn->Text, i)) {
i++;
btn->Text = i.ToString();
}
}
I am writing a c program to do some calculations.It would really help me if I was able to get responses by clicks of mouse.
How can i do this also If it is not possible then using which functions or libraries of C only would I be able to do that.
Ncurses has support for GPM (mouse library).
Excerpt from Ncurses interfacing with the mouse how-to:
Once a class of mouse events have been enabled, getch() class of functions return KEY_MOUSE every time some mouse event happens. Then the mouse event can be retrieved with getmouse().
The code approximately looks like this:
MEVENT event;
ch = getch();
if(ch == KEY_MOUSE)
if(getmouse(&event) == OK)
. /* Do some thing with the event */
.
.
getmouse() returns the event into the pointer given to it. It's a structure which contains
typedef struct
{
short id; /* ID to distinguish multiple devices */
int x, y, z; /* event coordinates */
mmask_t bstate; /* button state bits */
}
The bstate is the main variable we are interested in. It tells the button state of the mouse.
Then with a code snippet like the following, we can find out what happened.
if(event.bstate & BUTTON1_PRESSED)
printw("Left Button Pressed");
ok, here is the story...
I have 3 textfield for user to select....
[textfield A][textfield B][textfield C]
and a confirm button, the user need to add three textfield, after that , the user need to click the confirm button.... but based on different select order, the result is different, for example:
A>B>C, I will show red.
When the user select in this order:
B>A>C I will show green.
When the user select in this order:
C>B>A I will show the color blue....
based on different user select order, it will show different color....
But the question is, when I add more and more textfield, how can I implement this logic?
First, I design to have an array , when the user select one textfield, I store the textfield id to array, when user select the second one, I will store in the array, until the user click confirm, I read back the array to display the color....
But I think it will become very big & messy when more and more textfield is added, any better ideas? Thank you.
It's a bit of a hack, but what I'd be inclined to do is store the selections in a string that gets appended to each time (starting with empty string of course), trimming to the rightmost x characters. Then you can do a simple switch/case statement to determine the color. For example (C# fragments, sort of):
string selectStr = string.Empty;
void Select(string btn) {
selectStr += btn;
selectStr = selectStr.Remove(0, btn.Length - 3);
}
void Confirm() {
switch (selectStr) {
case "ABC" : /* make red */ break;
case "BAC" : /* make green */ break;
// etc.
}
}