Hello!
There must be a better way to do this! Let me explain as quickly as possible:
I have a system with an optical encoder, where I need to accomplish two things dependent on the encoder position (output):
1: I need to output a 3v3 “square wave” that is directly related to the position of the encoder. From encoder output 0 to 30, I write a pin LOW, from 30 to 60 I write that pin high, and so on, 48 times, alternating every 30 encoder counts. There's one exception, which makes sure the last 30 counts and the first 30 counts are the same state (LOW), which gives me a "missing tooth" indicator for a separate system. (The encoder count returns to zero every 360 degrees.)
Currently I read the encoder position, then write the pin30 HIGH or LOW via 48 lines of "if" statements. The speed of the encoder will vary between 0 to 50 rotations per second. I've tried using "else if" after the first if statement, but that doesn't work well (seems some counts are missed and stalls). This all seems super clunky to me.
2: At particular encoder positions I need to hold a second (and third) pin high or low. Currently that operation is happening as a separate function (void Move ()) which reads the encoder position and writes HIGH or LOW to the appropriate pin(s). Ideally I'd like to integrate them to save time and operations.
My highest concern at the moment is my large ugly 48 lines of if statements. I have to believe there’s a much better way to do this.
Thanks in advance for any thoughts you may have! The code below works, but ultimately I want to do other things and I'm worried this will bite me later on. I'm using the teensy 4.1.
Scott
There must be a better way to do this! Let me explain as quickly as possible:
I have a system with an optical encoder, where I need to accomplish two things dependent on the encoder position (output):
1: I need to output a 3v3 “square wave” that is directly related to the position of the encoder. From encoder output 0 to 30, I write a pin LOW, from 30 to 60 I write that pin high, and so on, 48 times, alternating every 30 encoder counts. There's one exception, which makes sure the last 30 counts and the first 30 counts are the same state (LOW), which gives me a "missing tooth" indicator for a separate system. (The encoder count returns to zero every 360 degrees.)
Currently I read the encoder position, then write the pin30 HIGH or LOW via 48 lines of "if" statements. The speed of the encoder will vary between 0 to 50 rotations per second. I've tried using "else if" after the first if statement, but that doesn't work well (seems some counts are missed and stalls). This all seems super clunky to me.
2: At particular encoder positions I need to hold a second (and third) pin high or low. Currently that operation is happening as a separate function (void Move ()) which reads the encoder position and writes HIGH or LOW to the appropriate pin(s). Ideally I'd like to integrate them to save time and operations.
My highest concern at the moment is my large ugly 48 lines of if statements. I have to believe there’s a much better way to do this.
Thanks in advance for any thoughts you may have! The code below works, but ultimately I want to do other things and I'm worried this will bite me later on. I'm using the teensy 4.1.
Scott
HTML:
#include <SPI.h>
int EPin = 6;* //setup of direction (DR) variable for EVAM
int IPin = 7;* //setup of direction (DR) variable for IVAM
int uiPot =38;
volatile int uiAdj = 0;
// three lines below are for LS7366R encoder init
int CS1 = 10;
long EncoderCount1;
char buff[4];
void QEC_Configure(void) //ls6366r configure
{
* SPI.begin();
* delay(5);
* digitalWrite(CS1, LOW);
* SPI.transfer(0x88);
* SPI.transfer(0x23);
* digitalWrite(CS1, HIGH);
} //END QEC_Configure()
void ReadEncoder(void) {
* long buff[4];
* digitalWrite(CS1, LOW);
* SPI.transfer(0x60); // Request count
* buff[0] = SPI.transfer(0x00); // most significant byte
* buff[1] = SPI.transfer(0x00);
* buff[2] = SPI.transfer(0x00);
* buff[3] = SPI.transfer(0x00); // least significant byte
* digitalWrite(CS1, HIGH);
* EncoderCount1 = (long)(buff[0] << 24) + (long)(buff[1] << 16) + (long)(buff[2] << 8) + (long)buff[3];
} //end ReadEncoder()
void CAPosition() {
* if (EncoderCount1 >= 0 && EncoderCount1 < 30 )digitalWrite (30, LOW);
* if (EncoderCount1 >= 30 && EncoderCount1 < 60 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 60* && EncoderCount1 < 90 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 90* && EncoderCount1 < 120 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 120* && EncoderCount1 < 150 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 150* && EncoderCount1 < 180 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 180* && EncoderCount1 < 210 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 210* && EncoderCount1 < 240 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 240* && EncoderCount1 < 270 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 270* && EncoderCount1 < 300 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 300* && EncoderCount1 < 330 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 330* && EncoderCount1 < 360 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 360* && EncoderCount1 < 390) digitalWrite (30, LOW);
* if (EncoderCount1 >= 390* && EncoderCount1 < 420 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 420* && EncoderCount1 < 450 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 450* && EncoderCount1 < 480 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 480* && EncoderCount1 < 510 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 510* && EncoderCount1 < 540 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 540* && EncoderCount1 < 570 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 570* && EncoderCount1 < 600 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 600* && EncoderCount1 < 630 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 630* && EncoderCount1 < 660 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 660* && EncoderCount1 < 690 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 690* && EncoderCount1 < 720 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 720* && EncoderCount1 < 750 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 750* && EncoderCount1 < 780 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 780* && EncoderCount1 < 810 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 810* && EncoderCount1 < 840 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 840* && EncoderCount1 < 870 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 870* && EncoderCount1 < 900 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 900* && EncoderCount1 < 930 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 930* && EncoderCount1 < 960 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 960* && EncoderCount1 < 990 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 990* && EncoderCount1 < 1020 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1020* && EncoderCount1 < 1050 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1050* && EncoderCount1 < 1080 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1080* && EncoderCount1 < 1110 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1110* && EncoderCount1 < 1140 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1140* && EncoderCount1 < 1170 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1170* && EncoderCount1 < 1200 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1200* && EncoderCount1 < 1230 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1230* && EncoderCount1 < 1260 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1260 && EncoderCount1 < 1290 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1290* && EncoderCount1 < 1320 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1320* && EncoderCount1 < 1350 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1350* && EncoderCount1 < 1380 ) digitalWrite (30, HIGH);
* if (EncoderCount1 >= 1380* && EncoderCount1 < 1410 ) digitalWrite (30, LOW);
* if (EncoderCount1 >= 1410* && EncoderCount1 < 1440 ) digitalWrite (30, LOW);
}//END CAPosition()
void serial () {
* Serial.print("Encoder1 = ");
* Serial.print(EncoderCount1);
* Serial.println ();
}
void Move() {
* if (EncoderCount1 >= 0 && EncoderCount1 <= 360) {
* * digitalWrite (IPin, LOW);} //O
* else
* {
* * digitalWrite (IPin, HIGH); //C
* } //
* if (EncoderCount1 >= 1080 && EncoderCount1 <= 1440) {
* * digitalWrite (EPin, LOW); //O
* }
* else
* {
* * digitalWrite (EPin, HIGH); //C
* } //
}// end move
void UI(){
* uiAdj = analogRead(uiPot);
* uiAdj = map(uiAdj, 0, 1024, 0, 200);
*
}
void setup() {
* // LS7366R Encoder setup
* Serial.begin(9600);
* pinMode(CS1, OUTPUT);
* digitalWrite(CS1, HIGH);
* QEC_Configure(); // QEC = Quadrature Encoder Counter
* // End encoder setup
* //===========================
* //PWM TIMER FOR MOTOR CONTROL
* //===========================
* //analogWrite(5, 128); //pin, duty cycle (duty 1 to 255, 128 is 50% duty cycle).
* analogWriteFrequency(5, 30621.09);* //sets driver PWM pin 5 to 36.621kHz 36621.09*
*
}/// end of setup
void loop() {
* ReadEncoder();
* //serial(); //serial print for diagnostics
* Move();
* CAPosition();
* UI();
* analogWrite(5, uiAdj); //pin, duty cycle (duty 1 to 255, 128 is 50% duty cycle).
}//end loop