encoder and tachometer class for EW3XX single board computer
Diff: EW305sbc.cpp
- Revision:
- 0:1d5bf13d7dbb
- Child:
- 1:b33d4964669b
diff -r 000000000000 -r 1d5bf13d7dbb EW305sbc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EW305sbc.cpp Thu Aug 15 19:21:44 2019 +0000 @@ -0,0 +1,208 @@ +//#include "mbed.h" +#include "EW305sbc.h" + + +EW305sbc::EW305sbc(int ch, int pulsesPerRev) + : ch_(ch), pulsesPerRev_(pulsesPerRev), spi(p5, p6, p7), ls7166_cs1(p19,1), ls7166_cs2(p20,1) +{ + init(); +} + +void EW305sbc::init() +{ + dt_ = 0.00625; // 125 Hz + speed_ = 0.0; // initial distance + countp_ = 0; + count_ = 0; + /** configure the rising edge to start the timer */ + updater.attach(callback(this, &EW305sbc::recalc), 0.00625); // 125 Hz, syntax from https://os.mbed.com/forum/mbed/topic/1964/?page=1 + wait(.2); //delay at beginning for voltage settle purposes + + // initialize channel 1 encoder by + LS7366_reset_counter(ch_); + LS7366_quad_mode_x4(ch_); + LS7366_write_DTR(ch_,0); +} + + +void EW305sbc::recalc() +{ + // Read encoder + count_ = -LS7366_read_counter(ch_); // input is the encoder channel + + // Estimate speed (counts/sec) + speed_ = (count_-countp_)/0.00625*2.0*3.14159/(4.0*pulsesPerRev_); + + // Age variable + countp_ = count_; +} + + +int EW305sbc::getCount(void) +{ + return count_; +} + +float EW305sbc::getSpeed(void) +{ + return speed_; +} + + + + + + +//---- Function Listing ------------------------------- + +//----- LS7366 Encoder/Counter Routines -------------------- +void EW305sbc::LS7366_cmd(int inst, int reg) +{ + char cmd; + spi.format(8, 0); + spi.frequency(2000000); + cmd = (inst << 6) | (reg << 3); +// printf("\r\ncmd=0X%2X", cmd); + spi.write(cmd); +} + +long EW305sbc::LS7366_read_counter(int chan_num) +{ + union bytes { + char byte_enc[4]; + long long_enc; + } counter; + + counter.long_enc = 0; + spi.format(8, 0); + spi.frequency(2000000); + + if(chan_num!=2) { + ls7166_cs1 = 0; + wait_us(1); + LS7366_cmd(LOAD,OTR);//cmd = 0xe8, LOAD to OTR + ls7166_cs1 = 1; + wait_us(1); + ls7166_cs1 = 0; + } else { + ls7166_cs2 = 0; + wait_us(1); + LS7366_cmd(LOAD,OTR);//cmd = 0xe8, LOAD to OTR + ls7166_cs2 = 1; + wait_us(1); + ls7166_cs2 = 0; + } + wait_us(1); + LS7366_cmd(RD,CNTR); //cmd = 0x60, READ from CNTR + counter.byte_enc[3] = spi.write(0x00); + counter.byte_enc[2] = spi.write(0x00); + counter.byte_enc[1] = spi.write(0x00); + counter.byte_enc[0] = spi.write(0x00); + + if(chan_num!=2) { + ls7166_cs1 = 1; + } else { + ls7166_cs2 = 1; + } + + return counter.long_enc; //return count +} + +void EW305sbc::LS7366_quad_mode_x4(int chan_num) +{ + + spi.format(8, 0); + spi.frequency(2000000); + + if(chan_num!=2) { + ls7166_cs1 = 0; + } else { + ls7166_cs2 = 0; + } + wait_us(1); + LS7366_cmd(WR,MDR0);// Write to the MDR0 register + wait_us(1); + spi.write(0x03); // X4 quadrature count mode + if(chan_num!=2) { + ls7166_cs1 = 1; + } else { + ls7166_cs2 = 1; + } +} + +void EW305sbc::LS7366_reset_counter(int chan_num) +{ + spi.format(8, 0); // set up SPI for 8 data bits, mode 0 + spi.frequency(2000000); // 2MHz SPI clock + + if(chan_num!=2) { // activate chip select + ls7166_cs1 = 0; + } else { + ls7166_cs2 = 0; + } + wait_us(1); // short delay + LS7366_cmd(CLR,CNTR); // Clear the counter register + if(chan_num!=2) { // de-activate chip select + ls7166_cs1 = 1; + } else { + ls7166_cs2 = 1; + } + wait_us(1); // short delay + + if(chan_num!=2) { // activate chip select + ls7166_cs1 = 0; + } else { + ls7166_cs2 = 0; + } + wait_us(1); // short delay + LS7366_cmd(LOAD,CNTR); // load counter reg + if(chan_num!=2) { // de-activate chip select + ls7166_cs1 = 1; + } else { + ls7166_cs2 = 1; + } +} + +void EW305sbc::LS7366_write_DTR(int chan_num, long enc_value) +{ + union bytes { // Union to speed up byte writes + char byte_enc[4]; + long long_enc; + } counter; + + spi.format(8, 0); // set up SPI for 8 data bits, mode 0 + spi.frequency(2000000); // 2MHz SPI clock + + counter.long_enc = enc_value; // pass enc_value to Union + + if(chan_num!=2) { // activate chip select + ls7166_cs1 = 0; + } else { + ls7166_cs2 = 0; + } + wait_us(1); // short delay + LS7366_cmd(WR,DTR); // Write to the Data Transfer Register + spi.write(counter.byte_enc[3]); // Write the 32-bit encoder value + spi.write(counter.byte_enc[2]); + spi.write(counter.byte_enc[1]); + spi.write(counter.byte_enc[0]); + if(chan_num!=2) { // de-activate the chip select + ls7166_cs1 = 1; + } else { + ls7166_cs2 = 1; + } + + wait_us(1); // short delay + if(chan_num!=2) { // activate chip select + ls7166_cs1 = 0; + } else { + ls7166_cs2 = 0; + } + wait_us(1); // short delay + LS7366_cmd(LOAD,CNTR); // load command to the counter register from DTR + if(chan_num!=2) { // de-activate chip select + ls7166_cs1 = 1; + } else { + ls7166_cs2 = 1; + } +} \ No newline at end of file