Replacement firmware for Dawson Dynamic OB dish positioner

Dependencies:   ConfigFile PCF8574 TextOLED mbed

Fork of mbed_blinky by Mbed

Revision:
14:ce9c322f95f2
Parent:
4:81cea7a352b0
--- a/main.cpp	Sat Sep 17 08:46:24 2016 +0000
+++ b/main.cpp	Sun Aug 20 21:30:40 2017 +0000
@@ -1,12 +1,640 @@
 #include "mbed.h"
+#include "PCF8574.h"
+#include <string>
+#include "ConfigFile.h"
+ 
+LocalFileSystem local("local");
+ConfigFile cfg;
+
+//Address of PCF8574 Button and LCD interface IC's
+#define PCF8574_BUTTON_ADDR 1  //A0
+#define PCF8574_LCD_ADDR 0  
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+
+//controller pins
+DigitalOut Select_AZ (p20);
+DigitalOut Select_EL (p16);
+DigitalOut Direction (p25);
+PwmOut Drive (p26);
+DigitalIn Endstop_AZ (p18);
+DigitalIn Endstop_EL (p15);
+InterruptIn Pulse(p17);
+DigitalOut rfled(p12);
+
+//LCD pin connections to PCF8574
+#define rs_pin 0
+#define e_pin 1
+#define d4_pin 2 
+#define d5_pin 3
+#define d6_pin 4
+#define d7_pin 5
+
+//scaling for pulses per degree
+#define Az_scale = 15.378
+#define El_scale = 5.155
+
+PCF8574 pcf_lcd(p9,p10,PCF8574_LCD_ADDR,true);
+PCF8574 pcf_button(p9,p10,PCF8574_BUTTON_ADDR,true); 
+
+Ticker Refresh_timer;
 
-DigitalOut myled(LED1);
+int _column;
+int _row;
+int Az_Count;
+int El_Count;
+char buffer[20];   
+char Last_Direction=0;
+char Up=0,Down=0,Left=0,Right=0,OK=0;
+float Azimuth,Elevation;
+float pwm_freq=0.00005;//30khz
+float pwm_duty=0.5;
+float Az_ref=0,El_ref=0;
+float Az_zero=0;
+float El_zero=0;
+int temp;         
+float temp2;
+
+
+//settings available in menu
+int setting_count=6;
+int setting_val[] = {0,270,0,60,Az_zero,El_zero};
 
+char * const setting_name[] = {
+     "Az CCW Limit:",
+     "Az CW Limit:",
+     "El Low Limit:",
+     "El High Limit:",
+     "Set Current Az:",
+     "Set Current El:",
+};
+
+
+
+
+void writeByte(int byte);
+void writeCommand(int command);
+void locate(int column, int row);
+void cls();
+void init();
+void write4bit(int value);
+void character(int column, int row, int c);
+int address(int column, int row);
+void writeData(int data);
+void writestring(int column, int row, string c);
+void count_rise();
+void count_fall();
+void Refresh_oled(bool anytime);
+void menu(void);
+void WriteSettings(void);
+void ReadSettings(void);
+
+
+
+//start of main program
 int main() {
+    uint8_t val;
+
+    El_Count=0;
+    Az_Count=0;
+    
+    Endstop_AZ.mode(PullUp);
+    Pulse.mode(PullUp);
+    
+    rfled=0;
+
+    pcf_button=0xff;
+    
+    
+    if(cfg.read("/local/settings.cfg")){
+        char cfgval[10];
+        for(int i=0;i<setting_count;i++){
+          cfg.getValue(setting_name[i], &cfgval[0], sizeof(setting_val));
+          setting_val[i]=atoi(cfgval);
+        }
+    }
+
+    init();
+    sprintf(buffer,"Az/El Controller");
+    writestring(2,0,buffer);
+    sprintf(buffer,"M0DTS 2017");
+    writestring(4,1,buffer);
+    sprintf(buffer,"rob@m0dts.co.uk");
+    writestring(2,2,buffer);
+    wait(2);
+    cls();
+    sprintf(buffer,"Az/El Controller");
+    writestring(0,0,buffer);
+
+    
+    Refresh_oled(true);
+    
+    Pulse.rise(&count_rise);
+    Pulse.fall(&count_fall);
+    Drive.period(pwm_freq);
+    
+    
+                
+              
     while(1) {
-        myled = 1;
-        wait(0.2);
-        myled = 0;
-        wait(0.2);
+        
+        val = pcf_button.read();
+        Up = ~(val>>3)&0x01;
+        Left = ~(val>>4)&0x01;
+        Right = ~(val>>5)&0x01;
+        Down = ~(val>>6)&0x01;
+        OK = ~(val>>7)&0x01;
+
+        if(OK){
+            //menu
+            menu();
+            wait_ms(200);
+            cls();
+            sprintf(buffer,"Az/El Controller");
+            writestring(0,0,buffer);
+            Refresh_oled(true);
+            }
+        
+        
+        if(Up){
+            Last_Direction=0;
+            Select_EL=1;
+            Select_AZ=0;
+            Direction=1;
+            temp2 = 0.1;
+            Drive.write(temp2);
+            while(Up & Elevation<=setting_val[3]){
+                if(temp2<pwm_duty){
+                    temp2+=0.01;
+                    Drive.write(temp2);
+                }
+                Up = ~(pcf_button.read()>>3)&0x01;
+                Refresh_oled(false);
+            }
+            Drive.write(0.0f);
+            wait_ms(100);
+            Up=0;
+            Refresh_oled(true);
+        }
+        
+        if(Down){
+            if(!Endstop_EL){
+                Last_Direction=1;
+                Select_EL=1;
+                Select_AZ=0;
+                Direction=0;
+                temp2 = 0.1;
+                Drive.write(temp2);
+                while(Down & !Endstop_EL & Elevation>=setting_val[2]){
+                        if(temp2<pwm_duty){
+                            temp2+=0.01;
+                            Drive.write(temp2);
+                        }
+                    Down = ~(pcf_button.read()>>6)&0x01;
+                    Refresh_oled(false);
+                }
+                Drive.write(0.0f);
+                wait_ms(100);
+                Down=0;
+                Refresh_oled(true);
+            }
+        }
+        
+        if(Left){
+            if(!Endstop_AZ){
+                Last_Direction=2;
+                Select_EL=0;
+                Select_AZ=1;
+                Direction=1;
+                temp2 = 0.1;
+                Drive.write(temp2);
+                while(Left & !Endstop_AZ & Azimuth>=setting_val[0]){
+                    if(temp2<pwm_duty){
+                        temp2+=0.01;
+                        Drive.write(temp2);
+                        }
+                    Left = ~(pcf_button.read()>>4)&0x01;
+                    Refresh_oled(false);
+                }
+                Drive.write(0.0f);
+                wait_ms(100);
+                Left=0;
+                Refresh_oled(true);
+            }
+        }   
+        
+        if(Right){
+            Last_Direction=3;
+            Select_EL=0;
+            Select_AZ=1;
+            Direction=0;
+            temp = Az_Count;
+            temp2 = 0.1;
+            Drive.write(temp2);
+            while(Right & Azimuth<=setting_val[1]){
+                if(temp2<pwm_duty){
+                    temp2+=0.01;
+                    Drive.write(temp2);
+                }
+                Right = ~(pcf_button.read()>>5)&0x01;
+                Refresh_oled(false);
+            }
+            Drive.write(0.0f); 
+            wait_ms(100);
+            Right=0;
+            Refresh_oled(true);
+        }
     }
 }
+
+void menu(void){
+    
+    //grab current az/el
+    
+    setting_val[4]=(int)Azimuth;
+    setting_val[5]=(int)Elevation;
+    
+    int pos=0;
+    cls();
+    sprintf(buffer,"Menu");
+    sprintf(buffer + strlen(buffer)," %i:",pos+1);
+    writestring(0,0,buffer);
+    sprintf(buffer,setting_name[pos]);
+    writestring(0,1,buffer);
+    sprintf(buffer,"    ");
+    writestring(0,2,buffer);
+    sprintf(buffer,"%i",setting_val[pos]);
+    writestring(0,2,buffer);
+    wait_ms(200);
+    
+    int val;
+    while(1){
+        val = pcf_button.read();
+        Up = ~(val>>3)&0x01;
+        Left = ~(val>>4)&0x01;
+        Right = ~(val>>5)&0x01;
+        Down = ~(val>>6)&0x01;
+        OK = ~(val>>7)&0x01;
+        
+        if(OK){
+            break;  
+        }
+        
+        if(Down){
+            cls();
+            pos++;
+            if (pos==setting_count){
+                pos=setting_count-1;
+            }
+            sprintf(buffer,"Menu");
+            sprintf(buffer + strlen(buffer)," %i:",pos+1);
+            writestring(0,0,buffer);
+
+            sprintf(buffer,setting_name[pos]);
+            writestring(0,1,buffer); 
+            sprintf(buffer,"    ");
+            writestring(0,2,buffer);
+            sprintf(buffer,"%i",setting_val[pos]);
+            writestring(0,2,buffer);
+            
+            if(pos==setting_count-1){
+                sprintf(buffer,"OK=Save");
+                writestring(13,3,buffer);
+            }
+            wait_ms(200);
+        }
+        
+        
+        if(Up){
+            pos--;
+            if (pos<0){pos=0;}
+            cls();
+            sprintf(buffer,"Menu");
+            sprintf(buffer + strlen(buffer)," %i:",pos+1);
+            writestring(0,0,buffer);
+            sprintf(buffer,setting_name[pos]);
+            writestring(0,1,buffer); 
+            sprintf(buffer,"    ");
+            writestring(0,2,buffer);
+            sprintf(buffer,"%i",setting_val[pos]);
+            writestring(0,2,buffer);
+            wait_ms(200);
+        }
+        
+        
+        if(Left){
+            switch (pos) {
+                case 0: 
+                if(setting_val[pos]>0){
+                    setting_val[pos]-=1;
+                }
+                break;
+                case 1: 
+                if(setting_val[pos]>setting_val[0]){
+                    setting_val[pos]-=1;
+                }
+                break;
+                case 2: 
+                if(setting_val[pos]>0){
+                    setting_val[pos]-=1;
+                }
+                break;
+                case 3: 
+                if(setting_val[pos]>setting_val[2]){
+                    setting_val[pos]-=1;
+                }
+                break;
+                case 4: 
+                if(setting_val[pos]>0){
+                    setting_val[pos]-=1;
+                }
+                break;
+                case 5: 
+                if(setting_val[pos]>0){
+                    setting_val[pos]-=1;
+                }
+                break;
+
+            }
+
+            sprintf(buffer,"    ");
+            writestring(0,2,buffer);
+            sprintf(buffer,"%i",setting_val[pos]);
+            writestring(0,2,buffer);
+            wait_ms(50);
+        }
+        
+        if(Right){
+            switch (pos) {    
+                case 0: //360
+                if(setting_val[pos]<setting_val[1]){
+                    setting_val[pos]+=1;
+                }
+                case 1: //360
+                if(setting_val[pos]<360){
+                    setting_val[pos]+=1;
+                }
+                break;
+                case 2: //90
+                if(setting_val[pos]<setting_val[3]){
+                    setting_val[pos]+=1;
+                }
+                break;
+                case 3: //90
+                if(setting_val[pos]<90){
+                    setting_val[pos]+=1;
+                }
+                break;
+                case 4: //360
+                if(setting_val[pos]<360){
+                    setting_val[pos]+=1;
+                }
+                break;
+                case 5: //90
+                if(setting_val[pos]<90){
+                    setting_val[pos]+=1;
+                }
+                break;
+            }
+
+            sprintf(buffer,"    ");
+            writestring(0,2,buffer);
+            sprintf(buffer,"%i",setting_val[pos]);
+            writestring(0,2,buffer);
+            wait_ms(50);
+        }
+    }
+    cls();
+    sprintf(buffer,"Saving...");
+    writestring(2,2,buffer);
+    
+    //store settings here
+    for(int i=0;i<setting_count;i++){
+      sprintf(buffer,"%i",setting_val[i]);
+      cfg.setValue(setting_name[i], buffer) ; 
+    }
+
+    cfg.write("/local/settings.cfg", "# Az/El Controller Settings");
+    cfg.removeAll();
+    
+    //reset counters.... big problem!
+    Az_Count=0;
+    El_Count=0;
+    
+    //save delay?!
+    wait_ms(300);
+}
+
+void count_rise(void){
+    if(Up|Right){
+        if(Up){
+            El_Count++;
+        }
+        if(Right){
+            Az_Count++;
+        }
+    //catch pulses after button released
+    }else{
+        if(Last_Direction==0)//up
+            El_Count++;
+        if(Last_Direction==3)//right
+            Az_Count++;    
+    }  
+}
+
+void count_fall(void){
+    if(Down|Left){
+        if(Down){
+            El_Count--;
+        }
+        if(Left){
+            Az_Count--;
+        }
+        //catch pulses after button released
+    }else{
+        if(Last_Direction==1)//down
+            El_Count--;
+        if(Last_Direction==2)//left
+            Az_Count--;   
+    }
+}
+
+
+void  Refresh_oled(bool anytime){
+        
+        Elevation = ((float)El_Count/15.378)+setting_val[5];
+        Azimuth = ((float)Az_Count/5.155)+setting_val[4];
+
+        if(Up){
+            sprintf(buffer,"El:% 05.1f",Elevation);
+            writestring(11,3,buffer);
+            buffer[0]=85;//'U'
+            buffer[1]=0;
+            writestring(19,3,buffer);
+            }
+        if(Down){
+            sprintf(buffer,"El:% 05.1f",Elevation);
+            writestring(11,3,buffer);
+            buffer[0]=68;//'D'
+            buffer[1]=0;
+            writestring(19,3,buffer);
+            }
+        if(Left){
+            sprintf(buffer,"Az:% 06.1f",Azimuth);
+            writestring(0,3,buffer);
+            buffer[0]=127;//arrow left
+            buffer[1]=0;
+            writestring(9,3,buffer);
+            }
+        if(Right){
+            sprintf(buffer,"Az:% 06.1f",Azimuth);
+            writestring(0,3,buffer);
+            buffer[0]=126;//arrow right
+            buffer[1]=0;
+            writestring(9,3,buffer);
+            }    
+               
+        if(!(Up|Down|Left|Right)){
+            sprintf(buffer," ");
+            writestring(9,3,buffer);
+            writestring(19,3,buffer);
+            if(anytime){
+                sprintf(buffer,"Az:% 06.1f",Azimuth);
+                writestring(0,3,buffer);
+                sprintf(buffer,"El:% 05.1f",Elevation);
+                writestring(11,3,buffer);
+            }
+            
+            if(Endstop_AZ|Endstop_EL){
+                if(Endstop_AZ){
+                    sprintf(buffer,"L");
+                    writestring(9,3,buffer);
+                }
+                
+                if(Endstop_EL){
+                    sprintf(buffer,"L");
+                    writestring(19,3,buffer);
+                }
+            }
+        }
+        
+   
+
+}
+
+
+//LCD routines ***********************************************************************************************
+
+void writeCommand(int command) {
+    pcf_lcd.write(rs_pin,0x00);
+    writeByte(command);
+}
+
+void writeData(int data) {
+    pcf_lcd.write(rs_pin,0x01);
+    wait_us(10);
+    writeByte(data);
+}
+
+void writeByte(int value) { 
+   //send MSB 4 bits
+    write4bit(value>>4);
+    //send LSB 4 bits
+    write4bit(value);
+}
+
+void writestring(int column, int row, string c) {
+    int a = address(column, row);
+    writeCommand(a);
+    for (int i = 0; c[i] != '\0'; i++){
+        writeData(c[i]);
+    } 
+}
+
+void write4bit(int value) {
+    pcf_lcd.write(d7_pin,(value>>3)&0x01);
+    pcf_lcd.write(d6_pin,(value>>2)&0x01);
+    pcf_lcd.write(d5_pin,(value>>1)&0x01);
+    pcf_lcd.write(d4_pin,value&0x01);
+    wait_us(10);
+    pcf_lcd.write(e_pin,0x01);
+    wait_us(10);
+    pcf_lcd.write(e_pin,0x00);
+}
+
+void cls() {
+    writeCommand(0x01); // cls, and set cursor to 0
+    wait_ms(2);     // This command takes 1.64 ms
+    locate(0, 0);
+}
+
+void locate(int column, int row) {
+    _column = column;
+    _row = row;
+}
+
+void init() {
+    //set default pin state for enable and reset
+    pcf_lcd.write(e_pin,0);
+    pcf_lcd.write(rs_pin,0); 
+  
+    //Enter 4bit mode, write 2 twice
+    write4bit(0x2);     //0010
+    write4bit(0x2);     //0010
+    write4bit(0x8);     //1000  english_japanese (default), 5x8 font, 2 line+
+    wait_ms(10);
+    
+    //display off, cursor off, blink off
+    writeCommand(0x8);
+    wait_ms(1);
+    
+    //clear display   
+    writeCommand(0x1);
+    wait_ms(1);
+    
+    //display home  
+    writeCommand(0x2);
+    wait_ms(1);
+    
+    //increment, no shift
+    writeCommand(0x6);
+    wait_ms(1);
+    
+    //display on, cursor off, blink off
+    writeCommand(0x0c);
+    wait_ms(1);
+    
+}
+
+void character(int column, int row, int c) {
+    int a = address(column, row);
+    writeCommand(a);
+    writeData(c);//data
+}
+
+
+
+int address(int column, int row) {
+    switch (row) {
+        case 0:
+            return 0x80 + column;
+        case 1:
+            return 0xc0 + column;
+        case 2:
+            return 0x94 + column;
+        case 3:
+            return 0xd4 + column;
+        default:
+            return 0x80 + column;
+    }
+}
+
+
+
+
+
+