|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Pet Maj 10, 2019 9:01 pm Naslov sporočila: |
|
|
Hi
Jaka, saj sem vedel, da ti to obvladaš. Program je posodobljen in deluje, ampak, ko pa zavrtim nazaj štej dol CCW, ko sem na 0.0, pa ko bi moral izpisati -0.1 ne izpiše minusa.
Minus izpiše šele, ko doseže -1.0
izpisuje takole:
0.0
0.1
....
....
0.9
-1.0
-1.2
....
Tukaj spodaj je pa celoten program:
Koda: |
#define encoder0PinA 2
#define encoder0PinB 3
volatile int count = 0;
int dec=0;
void setup() {
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // turn on pull-up resistor
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // turn on pull-up resistor
attachInterrupt(0, doEncoder, FALLING); // FALLING, RISING, CHANGE
Serial.begin (9600);
Serial.println("start"); // a personal quirk
}
void loop() {
Serial.print(count/10); // ko naredi encoder EN obrat (360 stop.)
Serial.print(".");
dec=count%10;
Serial.println (abs(dec)); //zaradi izpisa se znebimo minusa
delay(300);
}
void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
{
count++; // štej gor CW
}
else
{
count--; //štej dol CCW
}
}
void doEncoder_Expanded() {
if (digitalRead(encoder0PinA) == HIGH) { // found a low-to-high on channel A
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
count = count - 1; // CCW
}
else {
count = count + 1; // CW
}
}
else // found a high-to-low on channel A
{
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
count = count + 1; // CW
}
else {
count = count - 1; // CCW
}
}
}
|
Lp,marko |
|
Nazaj na vrh |
|
|
Jaka57 Moderator
Pridružen-a: Ned 12 Dec 2004 21:47 Prispevkov: 5777 Aktiv.: 25.86 Kraj: Grosuplje
|
Objavljeno: Pet Maj 10, 2019 10:02 pm Naslov sporočila: |
|
|
Ja, Marko drži, na to včeraj (danes ) ponoči nisem pomislil.
En If stavek bi moral to rešit, recimo:
Koda: |
void loop() {
dec=count%10;
if (count/10==0 && dec<0) Serial.print("-");
Serial.print(count/10); // ko naredi encoder EN obrat (360 stop.)
Serial.print(".");
Serial.println (abs(dec)); //zaradi izpisa se znebimo minusa
delay(300);
} |
_________________ Lp, Jaka |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Pet Maj 10, 2019 11:27 pm Naslov sporočila: |
|
|
Hi
Jaka, hvala in ostali. Sedaj pa to deluje tako kot mora.
Samo zanima me do katere hitrosti ga lahko obračam, kako se to zračuna?
Sedaj pa je to treba samo še na LCD napisat, bom probal tako kot je Igo predlagal.
LP,marko |
|
Nazaj na vrh |
|
|
Jaka57 Moderator
Pridružen-a: Ned 12 Dec 2004 21:47 Prispevkov: 5777 Aktiv.: 25.86 Kraj: Grosuplje
|
Objavljeno: Pet Maj 10, 2019 11:59 pm Naslov sporočila: |
|
|
Hm, preštet moraš prevedene strojne inštrukcije kontrolerja.
Večina inštrukcij se izvede v enem ciklu ure.
Torej 1500o/min=25o/s, kar pomeni, da imaš pri tej hitrosti 250 prekinitev na sekundo oz do prekinitve pride vsake 4ms. Da izvede eno strojno inštrukcijo pa potrebuje (velja za večino inštrukcij, ne pa za vse) mega328 pri 16MHz oscilatorju 0.625uS.
Sedaj pa kalkulator v roke in štet .
V glavnem v 4ms lahko izvede 6400 strojnih ciklov. _________________ Lp, Jaka |
|
Nazaj na vrh |
|
|
marko11 Član
Pridružen-a: Ned 14 Dec 2003 17:47 Prispevkov: 866 Aktiv.: 3.88 Kraj: Dobrepolje
|
Objavljeno: Tor Maj 14, 2019 4:19 pm Naslov sporočila: |
|
|
Jaka, hvala za razlago.
Tu spodaj je celotna koda , ki število ovojev izpisuje na LCD, upam, da sem codo pravilno sestavil.
Koda: |
#define encoder0PinA 2
#define encoder0PinB 3
#include <LiquidCrystal.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
volatile int count = 0;
int dec=0;
void setup() {
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // turn on pull-up resistor
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // turn on pull-up resistor
attachInterrupt(0, doEncoder, FALLING); // FALLING, RISING, CHANGE
//Serial.begin (9600);
//Serial.println("start"); // a personal quirk
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Stevec");
delay(1000);
}
void loop() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ovoji:");
lcd.setCursor(7,0);
dec=count%10;
if (count/10==0 && dec<0) lcd.print("-");
lcd.print(count/10);
lcd.print(".");
lcd.print (abs(dec)); //zaradi izpisa se znebimo minusa
delay(300);
}
void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
{
count++; // štej gor CW
}
else
{
count--; //štej dol CCW
}
}
void doEncoder_Expanded() {
if (digitalRead(encoder0PinA) == HIGH) { // found a low-to-high on channel A
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
count = count - 1; // CCW
}
else {
count = count + 1; // CW
}
}
else // found a high-to-low on channel A
{
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
count = count + 1; // CW
}
else {
count = count - 1; // CCW
}
}
}
|
Sedaj pa bi rad, da se na LCD v drugo vrstico izpišejo tudi trenutni obrati/minuto ( RPM ).
Na spletu sem našel kodo, ki deluje, jo pa ne znam "vkomponirati" v zgornjo kodo, da bi se to istočasno izvajalo.
lp,marko
Koda: |
unsigned long start;
const byte encoderPinA = 2;//A pin -> interrupt pin 0
const byte encoderPinB = 3;//B pin -> digital pin 3
volatile long pulse;
volatile bool pinB, pinA, dir;
const byte ppr = 10, upDatesPerSec = 2;
const int fin = 1000 / upDatesPerSec;
const float konstant = 60.0 * upDatesPerSec / (ppr * 2);
int rpm;
void setup() {
Serial.begin(9600);
attachInterrupt(0, readEncoder, CHANGE);
pinMode(encoderPinA,INPUT);
pinMode(encoderPinB,INPUT);
}
void loop() {
if(millis() - start > fin)
{
start = millis();
rpm = pulse * konstant;
Serial.println(rpm);
pulse = 0;
}
}
void readEncoder()
{
pinA = bitRead(PIND,encoderPinA);
pinB = bitRead(PIND,encoderPinB);
dir = pinA ^ pinB; // if pinA & pinB are the same
dir ? --pulse : ++pulse; // dir is CW, else CCW
}
|
|
|
Nazaj na vrh |
|
|
gustinmi Član
Pridružen-a: Tor 26 Feb 2019 13:41 Prispevkov: 14 Aktiv.: 0.22
|
Objavljeno: Sre Maj 22, 2019 2:21 pm Naslov sporočila: Naslov sporočila: Arduino UNO in encoder |
|
|
Encoder bi bilo res najbolj efektivno narediti v AVR zbirniku, z uporabo prekinitev na pinih (katerikoli PIN je lahko konfiguriran kot interrupt pin).
Rečeno je (za ATMEGA328, Arduino UNO):
"The interrupt execution response for all the enabled AVR interrupts is four clock cycles minimum."
To pomeni 4 x 62.5 ns se porabi za odziv na prekinitev (beri spremembo stanja na pinu). (16 MHZ).
Še opozorilo pred rabo DELAY - to dejansko blokira procesor in se dodaja na časovno os izvajanja. Ni najboljša strategija za merjenje nečesa.
Če ti slučajno zbirnik ni tuj, si poglej demo kodo za delo z prekinitvami : [url] https://github.com/gustinmi/avr-programming/blob/master/AssemblerApplication1/AssemblerApplication1/main.asm [/url] |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 88 dni
Powered by phpBB © 2001, 2005 phpBB Group
|