non

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
matthewhall115
Date:
Sun Nov 05 19:27:33 2017 +0000
Commit message:
none

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
mbedWSEsbc.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Nov 05 19:27:33 2017 +0000
@@ -0,0 +1,137 @@
+#include "mbed.h"
+#include "mbedWSEsbc.h"
+#define PI (3.14159)
+
+
+// Declare objects (if necessary)
+Ticker Controller; // declare Ticker object named "Controller"
+DigitalOut myled(LED1); // LED, flash lights for debugging
+
+
+// variables for data handling and storage
+float TotalTime;        // Total run time
+float Time;             // Current elapsed time
+float Ts = 0.0083;        // Control update period (seconds) (100 Hz equivalent)
+float Tstrm = 0.01;     // Data streaming period (seconds) (50 Hz equivalent)
+float usrDC;            // uaser-specified duty cycle
+float ang,angp,speed;   // variables for approximating speed from encoder measurements
+float dc;               // duty cycle applied to motor
+long enc1;              // encoder variable
+float lowDC;
+
+
+// Function definition Prototypes (declarations)
+void ctrCode(); // declare that a separate (other than main) function named "ctrCode" exists
+void twoStepCode(); //Two Step input
+
+
+// Enter main function
+int main ()
+{
+    // Initializes mbed to access functionality of encoder, A/D, driver, etc. chipsets
+    // Input is baud rate for PC communication
+    mbedWSEsbcInit(115200); // also initializes timer object t
+    mot_en1.period(0.020); // sets PWM period to 0.02 seconds for best DC motor operation
+
+    while(1) {
+
+        // Scan serial port for user input to begin experiment
+        pc.scanf("%f,%f",&TotalTime,&lowDC);
+
+        // perform necessary functions to time the experiment
+        Time = 0.0; // reset time variable
+        t.reset(); // reset timer object
+
+        // Attach the ctrCode function to ticker object specified with period Ts
+        Controller.attach(&twoStepCode,Ts);
+
+        t.start(); // start measuring elapsed time
+
+        // perform operations while the elapsed time is less than the desired total time
+        while(Time <= TotalTime) {
+
+
+
+            // read current elapsed time
+            Time = t.read();
+
+
+            // send data over serial port
+            pc.printf("%f,%f,%f\n",Time,speed,dc);
+
+
+            wait(Tstrm); // print data at approximately 50 Hz
+
+
+
+
+        } // end while(Time<=Ttime)
+
+        Controller.detach(); // detach ticker to turn off controller
+        // Turn motor off at end of experiment
+        mot_control(1,0.0);
+
+    }// end while(1)
+}// end main
+
+
+
+// Additional function definitions
+void ctrCode() // function to attach to ticker
+{
+
+    myled = !myled; // toggle LED 2 to indicate control update
+
+    // Read encoder
+    enc1 = LS7366_read_counter(1); // input is the encoder channel
+
+    // Convert from counts to radians
+    ang = 2.0*PI*enc1/6400.0;
+
+    // Estimate speed
+    speed = (ang-angp)/Ts;
+
+    // Age variables
+    angp = ang;
+
+    // compute duty cycle for motor (will be changed later!)
+    dc = usrDC; // user-specified duty cycle
+
+    // motor control
+    mot_control(1,dc); // first input is the motor channel, second is duty cycle
+
+} // end ctrCode()
+
+
+
+
+// Additional function definitions
+void twoStepCode() // function to attach to ticker
+{
+    myled = !myled; // toggle LED 2 to indicate control update
+
+    // Read encoder
+    enc1 = LS7366_read_counter(1); // input is the encoder channel
+
+    // Convert from counts to radians
+    ang = 2.0*PI*enc1/6400.0;
+
+    // Estimate speed
+    speed = (ang-angp)/Ts;
+
+    // Age variables
+    angp = ang;
+
+    // compute duty cycle for motor over two step inputs
+    if(Time<0.1) {
+        dc = 0.0;
+    } else if(Time<0.55) {
+        dc = lowDC; // low duty cycle
+    } else {
+        dc = 0.10;
+    }
+    // motor control
+    mot_control(1,dc); // first input is the motor channel, second is duty cycle
+} // end twoStepCode()
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Nov 05 19:27:33 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/b484a57bc302
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbedWSEsbc.h	Sun Nov 05 19:27:33 2017 +0000
@@ -0,0 +1,379 @@
+/* C Library for the WSE-PROJ-SBC
+ J Bradshaw
+ 20140912
+ 20140918 J Bradshaw - Found CS mistake in Encoder routines
+    Added comments in Init function, encoder functions
+ 20150210 J Bradshaw - Initialized DigitalOuts with pre-defined logic
+   levels (CS's high, etc)
+ 20161011 J Bradshaw - Changed MAX1270 ADC SCLK to 5MHz and format(12, 0)
+   for conversion mode to match datasheet (200ns SCLK max PW high and low)
+*/
+
+
+// LS7366 ENCODER IC DEFINITIONS
+//=============================================================================
+// Four commands for the Instruction Register (B7,B6) - LS7366
+//=============================================================================
+#define CLR     0x00    //Clear Instruction
+#define RD      0x01    //Read Instruction
+#define WR      0x02    //Write Instruction
+#define LOAD    0x03    //Load Instruction
+
+//=============================================================================
+// Register to Select from the Instruction Register (B5,B4,B3) - LS7366
+//=============================================================================
+#define NONE        0x00    //No Register Selected
+#define MDR0        0x01    //Mode Register 0
+#define MDR1        0x02    //Mode Register 1
+#define DTR         0x03    //Data Transfer Register
+#define CNTR        0x04    //Software Configurable Counter Register
+#define OTR         0x05    //Output Transfer Register
+#define STR         0x06    //Status Register
+#define NONE_REG    0x07    //No Register Selected
+
+// Set-up hardwired IO
+SPI spi_max1270(p5, p6, p7);
+SPI spi(p5, p6, p7);
+DigitalOut max1270_cs(p8, 1);  //CS for MAX1270 ADC (U3)
+DigitalOut max522_cs(p11, 1);  //CS for MAX522 DAC (U5)
+
+DigitalOut ls7166_cs1(p19, 1); //CS for LS7366-1 (U8)
+DigitalOut ls7166_cs2(p20, 1); //CS for LS7366-2 (U9)
+
+DigitalOut mot1_ph1(p21, 0);       
+DigitalOut mot1_ph2(p22, 0);
+PwmOut mot_en1(p23);
+
+DigitalOut mot2_ph1(p24, 0);
+DigitalOut mot2_ph2(p25, 0);
+PwmOut mot_en2(p26);
+
+DigitalOut led1(LED1, 0);
+DigitalOut led2(LED2, 0);
+DigitalOut led3(LED3, 0);
+DigitalOut led4(LED4, 0);
+
+Serial pc(USBTX, USBRX); // tx, rx for serial USB interface to pc
+Serial xbee(p13, p14); // tx, rx for Xbee
+Timer t; // create timer instance
+
+// ------ Prototypes -----------
+int read_max1270(int chan, int range, int bipol);
+float read_max1270_volts(int chan, int range, int bipol);
+void mot_control(int drv_num, float dc);
+void LS7366_cmd(int inst,  int reg);
+long LS7366_read_counter(int chan_num);
+void LS7366_quad_mode_x4(int chan_num);
+void LS7366_reset_counter(int chan_num);
+void LS7366_write_DTR(int chan_num,long enc_value);
+void write_max522(int chan, float volts);
+
+//---- Function Listing -------------------------------
+int read_max1270(int chan, int range, int bipol){
+    int cword=0x80;     //set the start bit
+    
+    spi_max1270.frequency(5000000); //5MHz Max
+    spi_max1270.format(8, 0);   // 8 data bits, CPOL0, and CPHA0 (datasheet Digital Interface)
+        
+    cword |= (chan << 4);   //shift channel
+    cword |= (range << 3);
+    cword |= (bipol << 2);
+            
+    max1270_cs = 0;
+           
+    spi_max1270.write(cword);
+    wait_us(15);    //15us    
+    spi_max1270.format(12, 0);
+    
+    int result = spi_max1270.write(0);
+    
+    max1270_cs = 1;
+    spi_max1270.format(8, 0);
+    return result;
+}
+
+float read_max1270_volts(int chan, int range, int bipol){
+    float rangevolts=0.0;
+    float volts=0.0;
+    int adc_res;
+
+    //read the ADC converter
+    adc_res = read_max1270(chan, range, bipol) & 0xFFF;
+        
+   //Determine the voltage range
+   if(range)  //RNG bit 
+     rangevolts=10.0;
+   else
+     rangevolts=5.0;
+             
+   //bi-polar input range
+   if(bipol){ //BIP is set, input is +/-
+     if(adc_res < 0x800){ //if result was positive
+      volts = ((float)adc_res/0x7FF) * rangevolts;      
+     }       
+     else{  //result was negative
+      volts = -(-((float)adc_res/0x7FF) * rangevolts) - (rangevolts * 2.0); 
+     }
+   }
+   else{  //input is positive polarity only
+      volts = ((float)adc_res/0xFFF) * rangevolts;   
+   }
+   
+   return volts;     
+}
+    
+//Motor control routine for PWM on 5 pin motor driver header
+// drv_num is 1 or 2 (defaults to 1, anything but 2)
+// dc is signed duty cycle (+/-1.0)
+
+void mot_control(int drv_num, float dc){        
+    if(dc>1.0)
+        dc=1.0;
+    if(dc<-1.0)
+        dc=-1.0;
+    
+    if(drv_num != 2){           
+        if(dc > 0.0){
+            mot1_ph2 = 0;
+            mot1_ph1 = 1;
+            mot_en1 = dc;
+        }
+        else if(dc < -0.0){
+            mot1_ph1 = 0;
+            mot1_ph2 = 1;
+            mot_en1 = abs(dc);
+        }
+        else{
+            mot1_ph1 = 0;
+            mot1_ph2 = 0;
+            mot_en1 = 0.0;
+        }
+    }                
+    else{
+        if(dc > 0.0){
+            mot2_ph2 = 0;
+            mot2_ph1 = 1;
+            mot_en2 = dc;
+        }
+        else if(dc < -0.0){
+            mot2_ph1 = 0;
+            mot2_ph2 = 1;
+            mot_en2 = abs(dc);
+        }
+        else{
+            mot2_ph1 = 0;
+            mot2_ph2 = 0;
+            mot_en2 = 0.0;
+        }
+    }                   
+}
+
+//----- LS7366 Encoder/Counter Routines --------------------
+void 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 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 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 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 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;    
+    }
+}   
+
+//------- MAX522 routines ---------------------------------
+void write_max522(int chan, float volts){
+    int cmd=0x20;   //set UB3
+    int data_word = (int)((volts/5.0) * 256.0);
+    if(chan != 2)
+        cmd |= 0x01;    //set DAC A out
+    else
+        cmd |= 0x02;    //set DACB out        
+    
+ //   pc.printf("cmd=0x%4X  data_word=0x%4X \r\n", cmd, data_word);
+    
+    spi.format(8, 0);
+    spi.frequency(2000000);
+    max522_cs = 0;
+    spi.write(cmd & 0xFF);
+    spi.write(data_word & 0xFF);
+    max522_cs = 1;    
+}
+
+void mbedWSEsbcInit(unsigned long pcbaud){
+    led1 = 0;           //Initialize all LEDs as off
+    led2 = 0;
+    led3 = 0;
+    led4 = 0;
+    max1270_cs = 1;     //Initialize all chip selects as off
+    max522_cs = 1;
+    ls7166_cs1 = 1;
+    ls7166_cs2 = 1;
+    
+    wait(.2);   //delay at beginning for voltage settle purposes
+    
+    mot_en1.period_us(50);   //20KHz for DC motor control PWM
+    pc.baud(pcbaud); //Set up serial port baud rate
+    pc.printf("\r\n");
+    xbee.baud(9600);
+    
+    LS7366_reset_counter(1);
+    LS7366_quad_mode_x4(1);       
+    LS7366_write_DTR(1,0);
+    
+    LS7366_reset_counter(2);
+    LS7366_quad_mode_x4(2);       
+    LS7366_write_DTR(2,0);
+          
+    t.start();  // Set up timer    
+}//mbedWSEsbc_init()
\ No newline at end of file