Toon posts:

Encoder met Arduino

Pagina: 1
Acties:

Vraag


  • stefan787
  • Registratie: Maart 2013
  • Laatst online: 07-05 11:52
Beste Tweakers!

op het moment ben ik bezig met een hobby project en probeer ik een eigen module te maken die mijn frequentieregelaar kan aansturen. Op deze module zit een lcd scherm en een encoder.
Met behulp van de encoder wil ik graag door een menu op het lcd schermpje kunnen scrollen.

Alleen het lukt mij niet om de encoder zo te programmeren dat hij netjes op en af telt. de uitkomst is niet stabiel en springt veel op en neer.

Op het internet zijn natuurlijk veel voorbeelden te vinden van een encoder alleen bij dit project wil ik graag dat als een getal boven een waarde komt dat ie dan weer naar nul gaat. en andersom van minimale naar maximale waarde. zodat ik als het waarde door. Ik hoop dat de flowchart hieronder duidelijkheid schept.

https://stefan787.stackstorage.com/s/PcfW8cZo5f5gB1U

uiteindelijk wil ik van de code die ik heb een functie maken zodat ik de
MaxValue, MinValue en StepSize
per pagina op het display kan aan passen.

dit is het overzicht van de opbouw van het uiteidelijke display:

https://stefan787.stackstorage.com/s/XMlnuzcbnCIczG7

Als ik dan bij Set RPM CW sta en ik klik dan op de schakelaar van de encoder dat ik dan vervolgens aan de encoder kan draaien en een toerental kan instellen.

Dan moeten de volgende waarde:
MaxValue, MinValue en StepSize
3000, 250 en 50 worden.

maar hiervoor heb ik eerste een goed werkende encoder nodig.

dit is de code die ik nu heb staan:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
 Name:      Main_V0.ino
 Created:   10/1/2018 5:12:10 PM
 Author:    Stefan de Kraker
 Flow chart: https://www.draw.io/#LFlow_Menu_frequentieregelaar.xml
*/


// encoder setup
const int OutputA = 2;
const int OutputB = 4;
const int OutputSW = 3;
int EncoderVal = 0;

// setup RPM
int Waarde = 0;
static int MaxValue = 3000;
static int MinValue = 250;


// setup Menu
int MenuLevel = 0;

void setup()
{
    pinMode(7, OUTPUT);
    pinMode(OutputA, INPUT);
    pinMode(OutputB, INPUT);
    pinMode(OutputSW, INPUT);
    digitalWrite(OutputSW, HIGH);
    Serial.begin(9600);
}


void loop() {
    int change = getEncoderTurn();
    EncoderVal = EncoderVal + change;
    overflow(1,6,1);
};

int getEncoderTurn() {
    static int oldA = HIGH;
    static int oldB = HIGH;
    int result = 0;
    int newA = digitalRead(OutputA);
    int newB = digitalRead(OutputB);
    if (newA != oldA || newB != oldB) {
        if (oldA == HIGH && newA == LOW)
        {
            result = (oldB * 2 - 1);
            //Serial.println("EncoderVal: ");
            //Serial.println(EncoderVal);
            Serial.println(Waarde);
        }
    }
    oldA = newA;
    oldB = newB;
        return result;
}
void overflow(int StepSize, int MaxValue, int MinValue) {
    if (EncoderVal >= 1) {
        Waarde = Waarde + StepSize;
        EncoderVal = 0;
    }
    if (EncoderVal == -1) {
        Waarde = Waarde - StepSize;
        EncoderVal = 0;
    }
    if (Waarde > MaxValue) {
        Waarde = MinValue;
    }
    if (Waarde < MinValue) {
        Waarde = MaxValue;
    }
}

Ik hoop dat iemand er naar kan kijken en mij kan helpen, ik ben hier namelijk al eigenlijk al te lang mee bezig wordt er nu een beetje :( van.

Alvast bedankt!! :)

[Voor 30% gewijzigd door stefan787 op 02-10-2018 08:51]

Beste antwoord (via stefan787 op 02-10-2018 20:16)


  • TommyboyNL
  • Registratie: Januari 2006
  • Niet online
Daar staat dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package nl.han.dea.fedor;

import nl.han.dea.fedor.adapters.KoenenDictionaryAdapter;
import nl.oose.dea.koenenkramers.KoenenDictionary;

public class DictionaryFactory {

    public static Dictionary create(String type) {
        if ("Koenen".equals(type)) {
            return new KoenenDictionaryAdapter(new KoenenDictionary());
//        } else if ("Kramers".equals(name)) {
            //           return new KramersDictionaryAdapter();
        }
        return null;
    }

}

Ik denk niet dat dit jouw code is...

Edit:

In het verleden heb ik deze library gebruikt, met dezelfde functionaliteit als jij; tussen 0 en x met rollover. Ik zal eens kijken of ik een snippet uit mijn code kan halen.

Edit2: Nee, te veel gedoe om mijn routines uit de rest van de code te slopen. Lelijke pseudocode uitgaande van bovenstaande library:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
init{
value = 1000; // Varieert van 100 tot 2000
rotary = read_rotary();
rotary_old = rotaty;
}

main{
label A;

rotary = read_rotary();
if (rotary == rotary_old) goto A;
value += (rotary-rotary_old);
if (value > 2000) vaule -= 1901; // Overflow
if (value < 100) value += += 1901; // Underflow
rotary_old = rotary;
}


Denkoefening voor jou: waarom niet "if (value == 2001) vaule -= 1901;"

[Voor 35% gewijzigd door TommyboyNL op 02-10-2018 22:27]

Alle reacties


Acties:
  • Beste antwoord
  • +1Henk 'm!

  • TommyboyNL
  • Registratie: Januari 2006
  • Niet online
Daar staat dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package nl.han.dea.fedor;

import nl.han.dea.fedor.adapters.KoenenDictionaryAdapter;
import nl.oose.dea.koenenkramers.KoenenDictionary;

public class DictionaryFactory {

    public static Dictionary create(String type) {
        if ("Koenen".equals(type)) {
            return new KoenenDictionaryAdapter(new KoenenDictionary());
//        } else if ("Kramers".equals(name)) {
            //           return new KramersDictionaryAdapter();
        }
        return null;
    }

}

Ik denk niet dat dit jouw code is...

Edit:

In het verleden heb ik deze library gebruikt, met dezelfde functionaliteit als jij; tussen 0 en x met rollover. Ik zal eens kijken of ik een snippet uit mijn code kan halen.

Edit2: Nee, te veel gedoe om mijn routines uit de rest van de code te slopen. Lelijke pseudocode uitgaande van bovenstaande library:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
init{
value = 1000; // Varieert van 100 tot 2000
rotary = read_rotary();
rotary_old = rotaty;
}

main{
label A;

rotary = read_rotary();
if (rotary == rotary_old) goto A;
value += (rotary-rotary_old);
if (value > 2000) vaule -= 1901; // Overflow
if (value < 100) value += += 1901; // Underflow
rotary_old = rotary;
}


Denkoefening voor jou: waarom niet "if (value == 2001) vaule -= 1901;"

[Voor 35% gewijzigd door TommyboyNL op 02-10-2018 22:27]


  • stefan787
  • Registratie: Maart 2013
  • Laatst online: 07-05 11:52
Bedankt voor je voorbeeld, ik ga eens kijken of ik dit kan toepassen!
Alleen nu zijn de stappen die value neemt nog steeds 1, hierover zou ik graag ook controle willen hebben dus dat de value met bijvoorbeeld 20 oploopt.

  • spork
  • Registratie: Maart 2009
  • Laatst online: 01-06 13:55
Dat is een kwestie van "value += (rotary-rotary_old);" vervangen door "value += 20*(rotary-rotary_old);"
Of elke andere willekeurige waarde natuurlijk.

  • stefan787
  • Registratie: Maart 2013
  • Laatst online: 07-05 11:52
Ik ben nu een aantal uurtjes bezig geweest met jullie tips.

En met succes. @TommyboyNL de libary heb ik toegepast en dit werkt echt een stuk beter.
Kan nu mooi door scrollen door me menu en met rollover. Daarnaast staat het nu ook in een functie die ik elke keer aan aan roepen met andere variabelen.

het display heb ik nu nog niet even gebruikt, tijdelijk even een rij ledjes, en ik kan mooi elk led één voor één aan en uit zetten. en als ik bij het eerste ledje sta en ik klik op de knop van de encoder dan kan ik een andere led dimmen. `

https://stefan787.stackstorage.com/s/0bFSnhV99M0KgVi

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 Name:      Main_V0.ino
 Created:   10/1/2018 5:12:10 PM
 Author:    Stefan de Kraker
 Flow chart: https://www.draw.io/#LFlow_Menu_frequentieregelaar.xml
*/

// Setup Encoder
#include <Encoder.h>
Encoder Knop(3, 2);
const int OutputSW = 4;
int OldDraaiKnop = -999;
int Waarde;

// Setup LCD en Menu 
int MenuLevel = 0;
bool InMenu = false;
bool A; // EnterMenu
bool B; // ExitMenu

// Ledjes, dit gaat straks weer weg
int led1 = 12;
int led2 = 11;
int led3 = 10;
int led4 = 9;
int led5 = 7;


// Setup voor toerental en stapgroote en max toerental
int RPMCW;
int RPMCCW;
const int MAXPRM = 3000;
const int StepSizeRPM = 50;
float OutputRPMCW;

void setup() {
    //Serial.begin(9600);
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(led3, OUTPUT);
    pinMode(led4, OUTPUT);
    pinMode(led5, OUTPUT);
    // Setup Pullup voor EncoderSW
    pinMode(OutputSW, INPUT_PULLUP);
}

void loop()
{
    if (InMenu == false) {
        MenuLevel = ReadEncoderData(1, 4, 0);
        led();
        EnterMenu();
        //Serial.print(MenuLevel);
    }
    if (InMenu == true) {
        if (MenuLevel == 0) { // Set RPM CW
            ExitMenu();
            RPMCW = ReadEncoderData(StepSizeRPM, MAXPRM, 0);
            ConvertRPM();
            
        }
        if (MenuLevel == 1) { // Set RPM CCW
            ExitMenu();
            RPMCCW = ReadEncoderData(StepSizeRPM, MAXPRM, 0);
            //Serial.print(RPMCCW);
        }
    }
}

int ReadEncoderData(int StepSize, int Maxavalue, int Minvalue) {
    long DraaiKnop;
    DraaiKnop = Knop.read();
    if (DraaiKnop != OldDraaiKnop) {
        OldDraaiKnop = DraaiKnop;
    }
    if (DraaiKnop == 4) {
        Waarde = Waarde + StepSize;
        Knop.write(0);
    }
    if (DraaiKnop == -4) {
        Waarde = Waarde - StepSize;
        Knop.write(0);
    }
    if (Waarde > Maxavalue) {
        Waarde = Minvalue;
    }
    if (Waarde < Minvalue) {
        Waarde = Maxavalue;
    }
    return Waarde;
}

void EnterMenu() {
    if (digitalRead(OutputSW) == LOW) {
        A = true;
    }
    if (digitalRead(OutputSW) == HIGH && A == true) {
        InMenu = true;
        A = false;
    }
}

void ExitMenu() {
    if (digitalRead(OutputSW) == LOW) {
        B = true;
    }
    if (digitalRead(OutputSW) == HIGH && B == true) {
        InMenu = false;
        B = false;
    }
}

void ConvertRPM() {
    OutputRPMCW =  (float) RPMCW / 11.7;
    Serial.println(OutputRPMCW);
    analogWrite(led4, OutputRPMCW);
}

void led() {
    if (MenuLevel == 0) {
        digitalWrite(led1, HIGH);
    }
    else {
        digitalWrite(led1, LOW);
    }
    if (MenuLevel == 1) {
        digitalWrite(led2, HIGH);
    }
    else {
        digitalWrite(led2, LOW);
    }
    if (MenuLevel == 2) {
        digitalWrite(led3, HIGH);
    }
    else {
        digitalWrite(led3, LOW);
    }
    if (MenuLevel == 3) {
        digitalWrite(led4, HIGH);
    }
    else {
        digitalWrite(led4, LOW);
    }
    if (MenuLevel == 4) {
        digitalWrite(led5, HIGH);
    }
    else {
        digitalWrite(led5, LOW);
    }
}

  • TommyboyNL
  • Registratie: Januari 2006
  • Niet online
@stefan787 Mooi dat het je gelukt is, en ook netjes dat je je code post. Veel succes met de rest van je project.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21:27
Voor de goede orde, een dergelijke encoder wordt normaal gesproken (als de hardware geen peripheral heeft die encoders ondersteunt) op basis van edge-interrupts ingelezen. Het idee is dan om op de flanken van je puls/pulsen te kijken wat de status van de andere ingang is en op basis daar van op of af te tellen.

NB
Deze code
C++:
1
2
3
4
5
    long DraaiKnop;
    DraaiKnop = Knop.read();
    if (DraaiKnop != OldDraaiKnop) {
        OldDraaiKnop = DraaiKnop;
    }

kun je vereenvoudigen naar:
C++:
1
2
    long DraaiKnop = Knop.read();
    OldDraaiKnop = DraaiKnop;

op basis waarvan je kunt concluderen dat OldDraaiKnop overbodig is.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee