Go Down

Topic: probleem met 1x3 zelfgemaakt keypad te verbinden met arduino (Read 158 times) previous topic - next topic

imiverse

Hallo iedereen,

ik heb een probleempje met mijn keypad.
ik vermoedt dat het probleem zich in mijn code bevindt en niet aan mijn keypad zelf.
Ik zal kort even toelichten wat de bedoeling is van project om een betere achtergrond te creeren
Voor het project heb ik een led display gemaakt in de vorm van een gezicht.
Door middel van het keypad zou geswitched kunnen worden tussen 3 gezichten (blij , neutraal , droevig).
Mijn keypad bestaat uit drie toetsen.
Het is een zelfgemaakt keypad gemaakt van aluminium folie en papier.
Aan mijn keypad zijn 4 draadjes verbonden.
1 draad is verbonden met mijn arduino poort 4 als output en op high gezet.
De andere 3 draadjes zijn verbonden met A0,A1 en A2 en als input gezet.
Mijn theorie hier achter was dat wanneer er gedrukt werd op de knop de aluminium folie van poort 4 het folie van bv. poort A0 aanraakt ik via een digital read paart A0 als high zo kunnen uitlezen en zo dan via een while loop de leds die bij een blij gezichtje horen zo kunnen aanzetten.
Dit is echter niet gelukt wanneer ik mijin code compileer blijven mijn ledjes loopen tussen een neutraal gezichte en een droevig gezichtje zonder dat ik een toets van mijn keypad heb ingedrukt.
Ik heb al verschillende keren proberen te zoeken naar een antwoord voor mijn probleem maar zonder succes.

Ik post mijn volledige code hier omdat ik niet weet waar in mijn code ik een fout heb begaan en ik ook geen errors krijg die me in de juiste richting kunnen helpen. Ik hoop dat een paar frisse ogen kunnen spotten wat ik niet heb kunnen spotten tot nu toe.
Alvast hartelijk bedankt!

Code: [Select]

// leds parts of face
#define winkL 13//geel
#define eyeL 12//wit
#define winkR 11//paars
#define eyeR 10//grijs
#define face 9//rood
#define sadM 8//groen
#define toungM 7//oranje
#define neutralM 6// blauw
#define smileM 5 //paars2

//keys ->> input when pressed it touches de constant high one
#define smileK A0
#define neutralK A1
#define sadK  A2

//constant high one
#define rowOutput 4


//counts --> to keep track how many times a face is pressed

int smileCount= 0;
int neutralCount= 0;
int sadCount= 0;

//var
int smileVal=0;
int neutralVal=0;
int sadVal=0;



void setup() {
  // put your setup code here, to run once:
 //leds
pinMode(winkL,   OUTPUT);
pinMode(eyeL,    OUTPUT);
pinMode(winkR,   OUTPUT);
pinMode(eyeR,    OUTPUT);
pinMode(face,    OUTPUT);
pinMode(sadM,    OUTPUT);
pinMode(toungM,  OUTPUT);
pinMode(neutralM,OUTPUT);
pinMode(smileM,  OUTPUT);
//Constant
pinMode(rowOutput, OUTPUT);
//keys
pinMode(smileK,    INPUT);
pinMode(neutralK,  INPUT);
pinMode(sadK,      INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

digitalWrite(rowOutput, 1); //->attachemnet to keypad that is always high

 // reading if input becomes high == "being pressed"
smileVal=digitalRead(smileK);
neutralVal=digitalRead(neutralK);
sadVal=digitalRead(sadK);

//show happy face when pressed
while (smileVal== 1)
{
  digitalWrite(face,   smileVal);
  digitalWrite(eyeL,   smileVal);
  digitalWrite(eyeR,   smileVal);
  digitalWrite(smileM, smileVal);
  smileCount++;
  delay(1000);
  smileVal=0;
 
  reset();
 
 }

 //show neutral face when pressed
 while (neutralVal == 1)
{
  digitalWrite(face,   neutralVal);
  digitalWrite(eyeL,   neutralVal);
  digitalWrite(eyeR,   neutralVal);
  digitalWrite(neutralM,neutralVal);
  neutralCount++;
  delay(1000);
  neutralVal=0;
 
  reset();
 
 
 }

 //show sad face when pressed
 while (sadVal == 1)
{
  digitalWrite(face,   sadVal);
  digitalWrite(eyeL,   sadVal);
  digitalWrite(eyeR,   sadVal);
  digitalWrite(sadM, sadVal);
  sadCount++;
  delay(1000);
  sadVal=0;
 
  reset();
 
 
 
 
 }


}
//to reset de leds to low
void reset(){

digitalWrite(winkL, 0);
digitalWrite(eyeL, 0);
digitalWrite(winkR, 0);
digitalWrite(eyeR, 0);
digitalWrite(face, 0);
digitalWrite(sadM, 0);
digitalWrite(toungM, 0);
digitalWrite(neutralM, 0);
digitalWrite(smileM, 0);

 
}

shooter

een digitalOutput kan eigenlijk alleen HIGH/LOW zijn, bij jou zijn het INT en die kunnen zelfs negatief zijn.
zelfde voor een Input die kan eigenlijk alleen HIGH/LOW zijn (dat is wel hetzelfde als 0 en 1, maar is niet netjes.

Dan de hardware inputs, en zeker de Analog inputs die hebben een heel hoge weerstand en gaan alle kanten op zelfs als er alleen een draadje aanzit. Er zijn een paar oplossingen:
Gebruik
Code: [Select]
INPUT_PULLUP

Hierdoor is er in de processor een weerstand naar de 5V, waardoor de ingang als deze niet verbonden is met nul, altijd HIGH, en word LOW als je de Gnd eraan hangt of een andere uitgang LOW maakt.


dit kun je ook doen met een weerstand naar iedere ingang van bijvoorbeeld 10 kiloohm, dat kun je dan zowel naar de +5V of naar Gnd doen. Uiteraard moet je dan wel de aanraakdraad een andere waarde geven.
er bestaat een printje met een capacitieve sensor en dan heb je helemaal niets nodig, je hoeft je hand maar in de buurt te houden van een stripje en dat wordt dan al gedetecteerd, (heeft mijn zoon gebruikt in een spel) en ja ik heb ze liggen in een kast.


paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

MAS3

Hoi imiverse, welkom !

Als eerste wil ik even door het zure heen bijten, dan hebben we dat maar vast gehad.
Ik snap dat de site nieuw is voor je, en je waarschijnlijk het forum nog een beetje moet leren kennen.
Je hebt je vanmiddag geregistreerd, en meteen een vraag in het Engelse deel "LEDs and Multiplexing" geplaatst.
Het is geen probleem dat je daar een vraag hebt gesteld die helemaal niets met multipexing te maken heeft.
Maar het is niet de bedoeling dat je je vraag vervolgens hier in het Nederlandstalige deel herhaalt.
Want nu zijn er 2 plaatsen waar je vraag eventueel behandeld kan gaan worden, en dat gaat geheid tot verwarring leiden.
Bovendien ga je dan ook zonder twijfel de antwoorden uit die 2 threads combineren.
Dat is heel ondankbaar naar de helpers in beide threads.

Ik vind het kwalijk dat je in het Nederlandstalige deel hebt verzuimd te vertellen dat het om een examenopdracht gaat.
Geen idee wat voor examen het betreft, en of het jouw examen is, of dat van iemand anders (maar dat doet er niet zo toe).
Maar deze site is niet bedoeld om schoolwerk door anderen dan de betreffende student uit te laten voeren (hier gaat het juist ook om opleiden, en dat bereik je alleen door het zelf uit te voeren).
Ik ga er van uit dat dat ook niet jouw bedoeling was, maar in ieder geval is dat nu wel verteld.

Naast shooter's opmerkingen en verbeter voorstellen, wil ik ook nog iets bijdragen.
Jouw zelfgemaakte schakelaars, klinken mij als dingen die ook een capacitieve werking hebben (dat maakt ze dus condensatoren).
Het formaat van de contacten is daarbij van belang.
Die capaciteit kun je beïnvloeden door het aanraken of bijna aanraken van de contacten.
Dat betekent dus dat er al wat geregistreerd zou kunnen worden, als de "toetsen" nog niet eens ingedrukt zouden worden.
De kans dat dat werkelijk gebeurt is niet groot, maar wel aanwezig.
Dit betekent dat het mogelijk is om door aanraking van 1 van jouw toetsen, bij alle 3 de toetsen iets te registreren.
Ligt er uiteraard weer aan hoe ver de toetsen uit elkaar staan.
Dat is dus een extra reden om eens de werkwijzen die shooter aanhaalt te bekijken.

Jouw code bevat wat eigenaardigheden en valkuilen.
Zo'n valkuil is bijvoorbeeld wat bekend staat als blokkerende code.
Delay() is blokkerende code.
Het laat je controller niets anders doen dan spreekwoordelijk een hartslag en ademing (en tellen).
Is niet nodig en zonde van kostbare tijd.

En een regel die het statement while bevat, leidt tot blokkerende code, want dat is de aard van while.
Die while zegt dus:
Zolang (==while) er aan voorwaarde x wordt voldaan, moet je uitsluitend de code tussen de {curly braces} uitvoeren.
[edit]Dat betekent dus dat om uit de {} te komen, de inhoud van je voorwaarde zal moeten veranderen want anders zit je voor eeuwig opgesloten tussen die {} [/edit]

Nu heb jij dit in je code gezet (beetje ingekort om alleen de kwestie aan te wijzen):
Code: [Select]
smileVal=digitalRead(smileK);

//show happy face when pressed
while (smileVal== 1)
{
  digitalWrite(face,   smileVal);
  digitalWrite(eyeL,   smileVal);
  digitalWrite(eyeR,   smileVal);
  digitalWrite(smileM, smileVal);
  smileCount++;
  delay(1000);
  smileVal=0;
 
  reset();
 
 }


Je wist de waarde van smileVal tijdens het uitvoeren die voorwaardelijke code, dus de while lost zichzelf op.
Daarna wis je zelfs je display door middel van je reset() functie.
Daarmee is de while statement totaal onnodig geworden en is er een andere manier om hetzelfde te bereiken.

Verder is er een techniek die elektriciens en elektronici toepassen, die voorkomt dat er meerdere knop funcites tegelijkertijd worden uitgevoerd.
Die techniek zorgt ervoor dat wanneer er 1 knop word gedrukt, de andere knoppen worden geblokkeerd.
Dat kun je ook middels je code realiseren.
En als je er iets langer over nadenkt, kun je het zelfs zo maken dat er een prioriteit zit in de knoppen.

Dan teken je je gezichtje, doet een hele tijd niets, en wis je dat gezichtje dan zomaar weer.
Ook als het helemaal niet gewist hoeft te worden.
Je kunt ook het gezichtje pas wissen als er een ander of geen gezicht getoond moet worden.

Ik hoop dat je met deze tips wat kunt doen.
En ik ben benieuwd naar hoe jouw installatie er uit ziet.
Dus als je 'm af hebt, graag een plaatje er van in deze thread.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Go Up