Replacement firmware for Dawson Dynamic OB dish positioner

Dependencies:   ConfigFile PCF8574 TextOLED mbed

Fork of mbed_blinky by Mbed

main.cpp

Committer:
m0dts
Date:
2017-08-20
Revision:
14:ce9c322f95f2
Parent:
4:81cea7a352b0

File content as of revision 14:ce9c322f95f2:

#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;

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) {
        
        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;
    }
}