Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Arduino ILI9341 TFT Display Pitanja
#36
Evo jedan konkretan programcic za Arduino i opticki enkoder, moze pomoci.
PHP Code:
/*
   Hardware Timer as an Encoder interface.

   The STM32 Timers have the possibility of being used as an encoder interface.
   This can be both a quadrature encoder (mode 3) or pulse encoder with a signal to give direction (modes 1 and 2).
   The default behavior is for quadrature encoder.

   To avoid overflowing the encoder (which may or may not happen (although with 16 bits, it's likely), the following code
   will interrupt every time the number of pulses that each revolution gives to increment/decrement a variable (ints).

   This means that the total number of pulses given by the encoder will be (ints * PPR) + timer.getCount()

   Attached is also a bit of code to simulate a quadrature encoder.
   To test this library, make the connections as below:

   TIMER2 inputs -> Digital Pins used to simulate.
   D2 -> D4
   D3 -> D5

   COUNTING DIRECTION:
   0 means that it is upcounting, meaning that Channel A is leading Channel B

   EDGE COUNTING:

   mode 1 - only counts pulses on channel B
   mode 2 - only counts pulses on Channel A
   mode 3 - counts on both channels.

*/
#include "HardwareTimer.h"

#define MySer Serial2 //koji seriski port koristimo za komunikaciju (Serial=USB, Serial2=HW port 2)
#define BOARD_LED_PIN PC13
#define QEI_A_PIN PA0
#define QEI_B_PIN PA1
#define QEI_Z_PIN PA2
#define PPR   2000 //Pulses per revolution

HardwareTimer timer(2);

unsigned long time 0       //time variable for millis()
unsigned long ints 0;
unsigned long interval 0//variable for status updates...
char received 0;
unsigned long cnt 0;

//-----------------------------------------
//overflaw interpat
//-----------------------------------------
void func() {
 
 if (timer.getDirection()) {
 
   ints--;
 
 } else {
 
   ints++;
 
 }
}

void z_idx_func() {
 
 //
 
 toggleLED();
 
 //timer.setCount(0);

 
 TIM1->CNT 0;

 
 //if (timer.getDirection()) {
 
 //  ints--;
 
 //} else {
 
 //  ints++;
 
 //}
}

//-----------------------------------------
//setup
//-----------------------------------------
void setup() {

 
 MySer.begin(115200);
 
 MySer.println("Encoder APP started ...");

 
 //define the Timer channels as inputs.
 
 pinMode(QEI_A_PININPUT_PULLUP);  //channel A
 
 pinMode(QEI_B_PININPUT_PULLUP);  //channel B
 
 pinMode(QEI_Z_PININPUT_PULLUP);  //channel Z

 
 // Set up the built-in LED pin as an output and button:
 
 pinMode(BOARD_LED_PINOUTPUT);

 
 //configure timer as encoder
 
 //timer.setMode(0, TIMER_ENCODER); //set mode, the channel is not used when in this mode.
 
 timer.pause(); //stop...
 
 timer.setPrescaleFactor(4); //normal for encoder to have the lowest or no prescaler.
 
 timer.setOverflow(PPR);    //use this to match the number of pulse per revolution of the encoder. Most industrial use 1024 single channel steps.
 
 timer.setCount(0);          //reset the counter.
 
 timer.setEdgeCounting(TIMER_SMCR_SMS_ENCODER3); //or TIMER_SMCR_SMS_ENCODER1 or TIMER_SMCR_SMS_ENCODER2. This uses both channels to count and ascertain direction.
 
 timer.resume();                 //start the encoder...
 
 timer.attachInterrupt(0func); //channel doesn't mean much here either.
 
 timer.refresh(); //! important

 
 attachInterrupt(QEI_Z_PINz_idx_funcRISING);

}


//-----------------------------------------
//LOOP
//-----------------------------------------
void loop() {

 
 cnt timer.getCount();

 
 //encoder code
 
 if (millis() - interval >= 200) {
 
   MySer.print(cnt);
 
   MySer.print(" counts");
 
   //MySer.print("direction ");
 
   //MySer.println(timer.getDirection());
 
   MySer.print(" Full Revs: ");
 
   MySer.println(ints);
 
   interval millis(); //update interval for user.
 
 }

 
 if (cnt > (PPR 20) || cnt 20) {
 
   //tu smo +/- 50 count oko nule, upali led
 
   // digitalWrite(BOARD_LED_PIN, 0);
 
 } else {
 
   //ugasi led
 
   // digitalWrite(BOARD_LED_PIN, 1);
 
 }

 
 /*
     Protocol...

     if received r - reset counter.
     if received 1 - Mode 1 (Channel B counts)
     if received 2 - Mode 2 (Channel A counts)
     if received 3 - Mode 3 (Counts on both channels)
     if received 4 - Change prescaler to 4
     if received 0 - change prescaler to 1
     if received - - Increase Speed
     if received + - Decrease Speed
  */

 
 //take care of comms...

 
 if (MySer.available() > 0) {

 
   received MySer.read();

 
   if (received == 'r') {
 
     timer.setCount(0);  //reset the counter.
 
     ints 0;
 
   }
 
   if (received == '1'timer.setEdgeCounting(TIMER_SMCR_SMS_ENCODER1); //count only the pulses from input 1
 
   if (received == '2'timer.setEdgeCounting(TIMER_SMCR_SMS_ENCODER2); //count only the pulses from input 2
 
   if (received == '3'timer.setEdgeCounting(TIMER_SMCR_SMS_ENCODER3); //count on both channels (default of the lib).
 
   if (received == '4'timer.setPrescaleFactor(4); //only updates on overflow, so you need to wait for an overflow. Not really used...
 
   if (received == '0'timer.setPrescaleFactor(1); //only updates on overflow, so you need to wait for an overflow.

 
 }


}

//-----------------------------------------
//togle LED on board
//-----------------------------------------
void toggleLED() {
 
 digitalWrite(BOARD_LED_PIN, !digitalRead(BOARD_LED_PIN));

Reply


Messages In This Thread
Arduino ILI9341 TFT Display Pitanja - by ronovar - 10-08-2018, 12:48 PM
RE: Arduino ILI9341 TFT Display Pitanja - by mikikg - 04-13-2019, 10:01 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)