New Products Flash Sale
Thread Tools
Old Mar 19, 2015, 10:09 AM
papo is offline
Find More Posts by papo
Registered User
New York Ny/Newark Downtown Manhatt, New York, United States
Joined Dec 2003
121 Posts
i am almost ready can you help me

Quote:
Originally Posted by mrheat View Post
this is my mod with oled display adafruit connected via i2c, nice because you have a lot More input Pins free, the upper right is a pot ch5 the middle is a rotary enc that i try to get working upper left is TC switch, sry couldnt get a sharp Video with my mobile so made pics

i dont use it at the moment because i must find a solution to trim at least the center position, and im not very good at arduino code

here is my current code

Code:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#define OLED_RESET 6
Adafruit_SSD1306 display(OLED_RESET);

// config PPM
#define servoCentro 1500       //servo center value (us)
#define ppmLong 22500          //ppm frame
#define ppmPulso 300           //ppm pulse width
#define onState 0              //Polarity: 0 neg / 1 pos
#define sigPin 9               //ppm output pin
#define ppmMin 1000
#define ppmMax 2000

// config TX
#define CANALES 5              //number of channels
#define MODELOS 5              //total model memory
#define canalTh 2              //Throtle channel ID
#define potMin 0               //Pot min value
#define potMax 1023            //Por max value
#define txVer "ArduTX v1.1"
#define numBytesPorModelo 32
#define swTC 5
#define swDR 11


int ppm[CANALES];              //ppm output array
unsigned char sw_status=0x00;  //0:TC 1:DR 
unsigned int pots[CANALES];    //ADC data array
unsigned char inPots[CANALES] = {A1, A0, A2, A3, A6};    //Input pins array
unsigned char batPin = A7;
// nothing editable from here :)
// *****************************
unsigned char menuActual=0;
unsigned char menuSubActual=0;
unsigned char submenuActual=0;
unsigned char drSeleccion=0xFF;
unsigned char pantalla=0;
unsigned char menu=0;
unsigned char modeloActual=0;
unsigned char servoReversa;
unsigned char dual_rate_low[CANALES];
unsigned char dual_rate_hi[CANALES];
boolean displayReady=false;
int temporal=0;
int calibracion[CANALES][2];
char msgs[][19] = {
  "Main Menu",
  "Servo Direction", 
  "Dual Rates", 
  "Model Selection", 
  "Save data", 
  "Stick Calibration"
};

// timer1 setup
void configTimer1() {
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1A = 100;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);  // prescaler 8: 0.5us - 16mhz
  TIMSK1 |= (1 << OCIE1A);
  sei();  
}

// Interrupcion del timer
ISR(TIMER1_COMPA_vect){  
  static boolean state = true;
  TCNT1 = 0;
  if(state) {   
    digitalWrite(sigPin, onState);
    OCR1A = ppmPulso * 2;
    state = false;
  }
  else{   
    static byte cur_chan_numb;
    static unsigned int calc_rest;
    digitalWrite(sigPin, !onState);
    state = true;
    if(cur_chan_numb >= CANALES){
      cur_chan_numb = 0;
      calc_rest = calc_rest + ppmPulso; 
      OCR1A = (ppmLong - calc_rest) * 2;
      calc_rest = 0;
    }
    else{
      OCR1A = (ppm[cur_chan_numb] - ppmPulso) * 2;
      calc_rest = calc_rest + ppm[cur_chan_numb];
      cur_chan_numb++;
    }     
  }
}

void setup() {
  unsigned char i;
  // switches setuo
  pinMode(swTC, INPUT_PULLUP);
  pinMode(swDR, INPUT_PULLUP);
  digitalWrite(swTC, HIGH); // pullup
  digitalWrite(swDR, HIGH); // pullup
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  digitalWrite(2, HIGH); // pullup
  digitalWrite(3, HIGH); // pullup
  digitalWrite(4, HIGH); // pullup
  
  // zero state values for ppm
  ppm[0]=servoCentro;
  ppm[1]=servoCentro;
  ppm[2]=ppmMin;
  ppm[3]=servoCentro;
  ppm[4]=servoCentro;
  ppm[5]=servoCentro;

  //zero state config parameters

  // servo reverse: 0 normal, 1 reverse
  servoReversa=0b00000000;

  // dual rates por defecto
  for (i=0;i<=CANALES;i++) {
    dual_rate_low[i]=75;
    dual_rate_hi[i]=100;
  }

  // load data from eeprom
  //reseteaEeprom();
  modeloActual=cargaDatosEeprom(255);

 // LCD config
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print(txVer);
  display.setCursor(0,7);  
  display.print("(c) 2014");
  display.display();
  delay(2000);
  // ppm timer config
  pinMode(sigPin, OUTPUT);
  digitalWrite(sigPin, !onState);
  configTimer1();
}

void loop() {
  int i;
  int j=0;
  unsigned char tecla=0;
  int vBat;
  unsigned char valT;
  while(1) {
    vBat=analogRead(batPin);
    // read potentiometers
    readPots();
    readSwitches();
    
    // read keyboard value every 10th loop and store it
    // and set the values depending on the menu option
    displayReady=false;
    display.clearDisplay();
  if (pantalla==0) {
      // info screen
      unsigned char valBar;  
      display.setCursor(2,0);
      display.print("M: ");
    display.setCursor(30,0);
    display.print(modeloActual+1); 
      // throtle cut switch value
             // throtle cut
          if (bitRead(sw_status,0)==0) {
            display.setCursor(2, 57);
            display.print("TC");
          } else {
            display.setCursor(2, 57);
            display.print("  ");
          }
          // dual rates
          if (bitRead(sw_status,1)==0) {
             display.setCursor(45, 57);
            display.print("Rate: LO");
          } else {
             display.setCursor(45, 57);
             display.print("Rate: HI");
          }
      // batery Voltage
      display.setCursor(75, 0);
      display.print("Bat: ");  
      int voltajeBat=map(vBat,0,1023,0,100);
      display.setCursor(98, 0);
      display.print(voltajeBat);
      display.setCursor(120, 0);
      display.print("%");
    
          
      // draw the bars
      display.drawLine(64,9,64,42, WHITE);
      for (i=0;i<=4;i++) {
        // level bars
        valBar=pots[i]/11,5;
        display.drawRect(15,9+(i*8),98,3, WHITE);
        display.drawPixel(16+valBar,10+(i*8), WHITE);
        display.drawPixel(15+valBar,10+(i*8), WHITE);
        display.drawPixel(17+valBar,10+(i*8), WHITE);
        // servo reverse indicator
        if (bitRead(servoReversa, i)) {
          display.setCursor(8, 8+(i*8));
          display.print("R"); 
        } else {
          display.setCursor(8, 8+(i*8));
          display.print("N");      
        }
      }
    } 
    else {
      if (pantalla==1) {
         // main menu
         display.setCursor(0, 0);
         display.print(msgs[0]);
          for (i=1;i<=5;i++) {
              if (i==menuSubActual) {
              display.setCursor( 0, i*9);
              display.print("->");
              display.setCursor( 10, i*9);
              display.print(msgs[i]);
              } else {
              display.setCursor( 0, i*9);
              display.print("  ");
              display.setCursor( 10, i*9);
              display.print(msgs[i]);
              }
          }
      }

      if (pantalla==2) {
        if ( menuActual==1) {
          // servo reversing
          display.setCursor( 0, 0);
          display.print(msgs[menuActual]);
          for (i=0;i<=(CANALES-1);i++) {
            if (i==menuSubActual) {
              display.setCursor( 0, 8+i*8);
              display.print("->");                   
            } 
            else {
              display.setCursor( 0, 8+i*8);
              display.print("  ");                
            }
              display.setCursor( 10, 8+i*8);
            display.print("CH: ");
              display.setCursor( 22, 8+i*8);
            display.print(String(i+1));
            if (bitRead(servoReversa,i)) {
              display.setCursor( 26, 8+i*8);
              display.print(" - R");
            } 
            else {
              display.setCursor(  26, 8+i*8);
              display.print(" - N");
            }
          }
              display.setCursor( 55, 42);
          display.print("Mod: ");  
              display.setCursor( 75, 42);
          display.print(String(modeloActual+1));
        }

        if(menuActual==2) {
          // dual rates
          unsigned char contadorTemp=0;
          display.setCursor(0,0);
             display.print(msgs[menuActual]);
          for (i=0;i<=(CANALES-1);i++) {
            display.setCursor(0, 8+i*8);
            display.print("CH: ");
            display.setCursor(18, 8+i*8);
            display.print(String(i+1));
            if (menuSubActual==contadorTemp) {
              if (drSeleccion==contadorTemp) {
                display.setCursor(26, 8+i*8);
                   display.print("*");     
                 } 
              else {
                  display.setCursor(26, 8+i*8);
                   display.print(">");
              }
            }
          display.setCursor(30, 8+i*8);
               display.print("L:" ); 
               display.setCursor(42, 8+i*8);
               display.print(String(dual_rate_low[i]));
               contadorTemp++;               
               if (menuSubActual==contadorTemp) {
                 if (drSeleccion==contadorTemp) {
                 display.setCursor( 55, 8+i*8);
                   display.print("*");  
                 } else {
                   display.setCursor( 55, 8+i*8);
                   display.print(">");
                 }
               }
               display.setCursor(  60, 8+i*8);
               display.print("H:");
               display.setCursor(  70, 8+i*8);
               display.print(String(dual_rate_hi[i]));
               contadorTemp++;
          }
        }

        if (menuActual==3) {
          // model selection
           display.setCursor(  0, 0);
             display.print(msgs[menuActual]);
          for (i=0;i<=(MODELOS-1);i++) {
           display.setCursor(  8, 8+i*8);
                 display.print("Mod: ");
                 display.setCursor(  27, 8+i*8);
                 display.print(String(i+1) );
                 if (i==menuSubActual) {
                   display.setCursor(0, 8+i*8);
                    display.print("->" );                   
                 } else {
                   display.setCursor( 0, 8+i*8);
                    display.print("  ");                
                 }
                 
                 if (i==modeloActual) {
                   display.setCursor(35, 8+i*8);
                    display.print("*");
                 }
             }
          }
          
          
        if (menuActual==4) {
          // data save
          int eepromBase;
          eepromBase=numBytesPorModelo*modeloActual;
          unsigned char eepromPos =eepromBase;
          // actual model
          EEPROM.write(511,modeloActual);
          // servo reverse
          EEPROM.write(eepromPos, servoReversa);
          eepromPos++;
          // dual rates
          for (i=0;i<=CANALES;i++) {
            EEPROM.write(eepromPos, dual_rate_low[i]);
            eepromPos++;
            EEPROM.write(eepromPos, dual_rate_hi[i]);
            eepromPos++;
          }

          display.setCursor(  0, 20);
             display.print("Saving data for");
          display.setCursor(  0, 28);
             display.print("actual model:");
          display.setCursor(  0, 40);
             display.print(String(modeloActual+1));
          display.setCursor(  0, 42);
             display.print("...wait");
          pantalla--;
          menuActual=1;
          menuSubActual=1;
             display.display();
          delay(1000);
        }

        if (menuActual==5) {
          // gimbal calibration
          display.setCursor(  0, 0);
          display.print(msgs[menuActual]);
          display.display();
          delay(500);
          display.clearDisplay();
          for (i=0;i<=CANALES;i++) {
            calibracion[i][0]=512;
            calibracion[i][1]=512;
          }
          tecla=readKeys(); 
          while (tecla!=1) {
          display.clearDisplay();
          display.setCursor(  0, 0);
            display.print("Calibration");
            display.setCursor(  0, 8);
            display.print("Move the sitcks");
            display.setCursor(  0, 16);
            display.print("1: ");
            display.setCursor(20, 16);
            display.print(String(analogRead(inPots[0])));
            display.setCursor(  40, 16);
            display.print("2: ");
            display.setCursor(  60, 16);
            display.print(String(analogRead(inPots[1])));
            display.setCursor(  0, 24);
            display.print("3: ");
            display.setCursor(  20, 24);
            display.print(String(analogRead(inPots[2])));
            display.setCursor(  40, 24);
            display.print("4: ");
            display.setCursor(  60, 24);
            display.print(String(analogRead(inPots[3])));
            display.setCursor( 0, 32);
            display.print("5: ");
            display.setCursor( 20, 32);
            display.print(String(analogRead(inPots[4])));
            display.setCursor(   40, 32);
            display.print("6: ");
            display.setCursor(  60, 32);
            display.print(String(analogRead(inPots[5])));
          display.display();
            int lecturaTemporal;
            for (i=0;i<=(CANALES-1);i++) {
              lecturaTemporal=analogRead(inPots[i]);
              // min values
              if (lecturaTemporal<=calibracion[i][0]) {
                calibracion[i][0]=lecturaTemporal;
              }
              // max values
              if (lecturaTemporal>=calibracion[i][1]) {
                calibracion[i][1]=lecturaTemporal;
              }
              delay(10);
            }
            tecla=readKeys();
          }
          // save calibration data
          int posEeprom=0;
          for (i=0;i<=(CANALES-1);i++) {
            posEeprom=400+(i*4);
            EEPROMWriteInt(posEeprom, calibracion[i][0]); //min
            posEeprom+=2;
            EEPROMWriteInt(posEeprom, calibracion[i][1]); //max
          }
          display.clearDisplay();
          display.setCursor(  0, 20);
          display.print("Saving calibration");
          display.setCursor(  0, 28);
          display.print("data");
          display.setCursor(   0, 40);
          display.print("...wait");
          display.display();
          delay(1000);
          pantalla=0;
          menuActual=0;
          menuSubActual=0;
        }
      }

    }

    // screen update
    display.display();


    // read keyboard every 2 loops
    if (j>2) {
      tecla=readKeys(); 
      if (tecla==2) {
        if (pantalla<2) { 
          pantalla++; 
          menuActual=menuSubActual; 
          menuSubActual=0;
        } 
        else {
          // options for each menu
          if (menuActual==1) {
            // reversa de servos
            bitWrite(servoReversa, menuSubActual, !bitRead(servoReversa,menuSubActual));
          }
          if (menuActual==2) {
            // dual rates
            if (drSeleccion!=0xFF) {
              drSeleccion=0xFF;
            } 
            else {
              drSeleccion=menuSubActual;
            }
          }

          if (menuActual==3) {
            // model selection
            modeloActual=menuSubActual;
            // load data from eeprom
            EEPROM.write(511, modeloActual);
            cargaDatosEeprom(modeloActual);
            pantalla=0; 
            menuSubActual=0; 
            menuActual=0;
          }
        }
      }

      if (tecla==3) {
        switch (menuActual) {
        case 2:
          if (drSeleccion==0xFF) {
            if (menuSubActual<(CANALES*2)) { 
              menuSubActual++; 
              if (pantalla==0) {
                pantalla++; 
              }
            }
          } 
          else {
            if ((drSeleccion%2)==0) {
              if (dual_rate_low[drSeleccion/2]>0) { 
                dual_rate_low[drSeleccion/2]--;  
              }    
            } 
            else {
              if (dual_rate_hi[drSeleccion/2]>0) { 
                dual_rate_hi[drSeleccion/2]--;  
              } 
            }
          }
          break;
        default: 
          if (menuSubActual<6) { 
            menuSubActual++; 
            if (pantalla==0) {
              pantalla++; 
            }
          }
          break;
        }   

      }

      if (tecla==1) {
        switch (menuActual) {
        case 2:
          if (drSeleccion==0xFF) {
            if (menuSubActual==0) { 
              pantalla--; 
              menuSubActual=1; 
              menuActual=0;
            } 
            else { 
              menuSubActual--; 
            } 
          } 
          else {
            if ((drSeleccion%2)==0) {
              if (dual_rate_low[drSeleccion/2]<100) { 
                dual_rate_low[drSeleccion/2]++;  
              }
            } 
            else {
              if (dual_rate_hi[drSeleccion/2]<100) { 
                dual_rate_hi[drSeleccion/2]++;  
              } 
            }
          }
          break;
        default:
          if (menuSubActual>0) {
            menuSubActual--; 
          } 
          else {
            if (pantalla>0) { 
              pantalla--; 
              menuSubActual=1; 
              menuActual=0;
            }
          } 
          break;
        }
      }

      j=0;
    }
    j++;

  }
}

void readPots() {
  unsigned char i,j;
  int temporalPots[CANALES];
  for (i=0;i<=(CANALES-1);i++) {
    // read the pots     
    temporalPots[i]=analogRead(inPots[i]);
    // calibration mapping
    pots[i]=map(temporalPots[i],calibracion[i][0], calibracion[i][1], 0, 1023);
    // servo reversing
    if (bitRead(servoReversa,i)==1) {
      pots[i]=1023-pots[i]; 
    }

    // Throtle cut
    if (i==canalTh && bitRead(sw_status,0)==0) {
      // TC activado
      pots[i]=0;
    }

    // dual rates
    if (bitRead(sw_status,1)==0) {
      // low, rates
      pots[i]=ajusteDR(pots[i],dual_rate_low[i],i,canalTh);
    } 
    else {
      // hi rates 
      pots[i]=ajusteDR(pots[i],dual_rate_hi[i],i,canalTh);
    }  
    // map values to PPM
    ppm[i]=map(pots[i],potMin, potMax, ppmMin, ppmMax);
  }
}

void readSwitches() {
  // read switches and set into the sw_status var
  if (digitalRead(swTC)==HIGH) {
    bitWrite(sw_status,0,1);
  } 
  else {
    bitWrite(sw_status,0,0);
  }
  if (digitalRead(swDR)==HIGH) {
    bitWrite(sw_status,1,1);
  } 
  else {
    bitWrite(sw_status,1,0);
  }
}

unsigned char readKeys() {
  unsigned char salida;  
  salida = 0;
  if (digitalRead(4)==0) salida=3;
  if (digitalRead(2)==0) salida=2;
  if (digitalRead(3)==0) salida=1;
  // read analog keyboard
  delay(25);
  return salida;
}

int  freeRam () {
  // returns free ram in avr chip
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

unsigned char cargaDatosEeprom(unsigned char mod) {
  // load data from eeprom, for selected model
  int eepromBase;
  unsigned char i;
  if (mod=255) {
    mod=EEPROM.read(511);
  } 

  eepromBase=numBytesPorModelo*mod;
  unsigned char eepromPos=eepromBase;
  // servo reversing
  servoReversa=EEPROM.read(eepromPos);
  eepromPos++;
  // dual rates
  for (i=0;i<=CANALES-1;i++) {
    dual_rate_low[i]=EEPROM.read(eepromPos);
    eepromPos++;
    dual_rate_hi[i]=EEPROM.read(eepromPos);
    eepromPos++;
  }
  int posEeprom;
  for (i=0;i<=(CANALES-1);i++) {
    posEeprom=400+(i*4);
    calibracion[i][0]=EEPROMReadInt(posEeprom); //minimo
    posEeprom+=2;
    calibracion[i][1]=EEPROMReadInt(posEeprom); //maximo
  }

  return mod;
}

unsigned char reseteaEeprom() {
  // erases eeprom, just for checking values (unused now)
  int eepromBase, eepromPos;
  unsigned char i,j;
  EEPROM.write(511,0);
  for (j=0;j<=CANALES-1;j++) {
    eepromPos=numBytesPorModelo*j;
    EEPROM.write(eepromPos,0x00);
    eepromPos++;
    for (i=0;i<=CANALES-1;i++) {
      EEPROM.write(eepromPos,75);
      eepromPos++;
      EEPROM.write(eepromPos,100);
      eepromPos++;

    }
  }      
}


int ajusteDR(int valor, float dr, unsigned char canal, unsigned char canTh) {
  // dual rate calc
  int salida,temp;
  float mult;
  mult=dr;
  if (canal==canalTh) {
    salida=(int)valor*mult/100;  
  } 
  else {
    temp=valor-512;
    salida=(int)((temp*mult/100)+512);

  }
  salida=constrain(salida,0,1023);
  return salida;
}


void EEPROMWriteInt(int p_address, int p_value) {
  // write a 16bit value in eeprom
  byte Byte1 = ((p_value >> 0) & 0xFF);
  byte Byte2 = ((p_value >> 8) & 0xFF);
  EEPROM.write(p_address, Byte1);
  EEPROM.write(p_address + 1, Byte2);
}

int EEPROMReadInt(int p_address) {
  // read a 16 bit value in eeprom
  byte Byte1 = EEPROM.read(p_address);
  byte Byte2 = EEPROM.read(p_address + 1);
  long firstTwoBytes = ((Byte1 << 0) & 0xFF) + ((Byte2 << 8) & 0xFF00);
  return (firstTwoBytes);
}





can i get some help with the tx side of it i like the small lcd set up
parts list to buy i would appreciate it
papo is offline Find More Posts by papo
Last edited by papo; Mar 20, 2015 at 07:07 AM.
Reply With Quote
Sign up now
to remove ads between posts
Old Mar 20, 2015, 07:34 AM
papo is offline
Find More Posts by papo
Registered User
New York Ny/Newark Downtown Manhatt, New York, United States
Joined Dec 2003
121 Posts
can i get some help with tx setup

Quote:
Originally Posted by mrheat View Post
this is my mod with oled display adafruit connected via i2c, nice because you have a lot More input Pins free, the upper right is a pot ch5 the middle is a rotary enc that i try to get working upper left is TC switch, sry couldnt get a sharp Video with my mobile so made pics

i dont use it at the moment because i must find a solution to trim at least the center position, and im not very good at arduino code

here is my current code

Code:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#define OLED_RESET 6
Adafruit_SSD1306 display(OLED_RESET);

// config PPM
#define servoCentro 1500       //servo center value (us)
#define ppmLong 22500          //ppm frame
#define ppmPulso 300           //ppm pulse width
#define onState 0              //Polarity: 0 neg / 1 pos
#define sigPin 9               //ppm output pin
#define ppmMin 1000
#define ppmMax 2000

// config TX
#define CANALES 5              //number of channels
#define MODELOS 5              //total model memory
#define canalTh 2              //Throtle channel ID
#define potMin 0               //Pot min value
#define potMax 1023            //Por max value
#define txVer "ArduTX v1.1"
#define numBytesPorModelo 32
#define swTC 5
#define swDR 11


int ppm[CANALES];              //ppm output array
unsigned char sw_status=0x00;  //0:TC 1:DR 
unsigned int pots[CANALES];    //ADC data array
unsigned char inPots[CANALES] = {A1, A0, A2, A3, A6};    //Input pins array
unsigned char batPin = A7;
// nothing editable from here :)
// *****************************
unsigned char menuActual=0;
unsigned char menuSubActual=0;
unsigned char submenuActual=0;
unsigned char drSeleccion=0xFF;
unsigned char pantalla=0;
unsigned char menu=0;
unsigned char modeloActual=0;
unsigned char servoReversa;
unsigned char dual_rate_low[CANALES];
unsigned char dual_rate_hi[CANALES];
boolean displayReady=false;
int temporal=0;
int calibracion[CANALES][2];
char msgs[][19] = {
  "Main Menu",
  "Servo Direction", 
  "Dual Rates", 
  "Model Selection", 
  "Save data", 
  "Stick Calibration"
};

// timer1 setup
void configTimer1() {
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1A = 100;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);  // prescaler 8: 0.5us - 16mhz
  TIMSK1 |= (1 << OCIE1A);
  sei();  
}

// Interrupcion del timer
ISR(TIMER1_COMPA_vect){  
  static boolean state = true;
  TCNT1 = 0;
  if(state) {   
    digitalWrite(sigPin, onState);
    OCR1A = ppmPulso * 2;
    state = false;
  }
  else{   
    static byte cur_chan_numb;
    static unsigned int calc_rest;
    digitalWrite(sigPin, !onState);
    state = true;
    if(cur_chan_numb >= CANALES){
      cur_chan_numb = 0;
      calc_rest = calc_rest + ppmPulso; 
      OCR1A = (ppmLong - calc_rest) * 2;
      calc_rest = 0;
    }
    else{
      OCR1A = (ppm[cur_chan_numb] - ppmPulso) * 2;
      calc_rest = calc_rest + ppm[cur_chan_numb];
      cur_chan_numb++;
    }     
  }
}

void setup() {
  unsigned char i;
  // switches setuo
  pinMode(swTC, INPUT_PULLUP);
  pinMode(swDR, INPUT_PULLUP);
  digitalWrite(swTC, HIGH); // pullup
  digitalWrite(swDR, HIGH); // pullup
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  digitalWrite(2, HIGH); // pullup
  digitalWrite(3, HIGH); // pullup
  digitalWrite(4, HIGH); // pullup
  
  // zero state values for ppm
  ppm[0]=servoCentro;
  ppm[1]=servoCentro;
  ppm[2]=ppmMin;
  ppm[3]=servoCentro;
  ppm[4]=servoCentro;
  ppm[5]=servoCentro;

  //zero state config parameters

  // servo reverse: 0 normal, 1 reverse
  servoReversa=0b00000000;

  // dual rates por defecto
  for (i=0;i<=CANALES;i++) {
    dual_rate_low[i]=75;
    dual_rate_hi[i]=100;
  }

  // load data from eeprom
  //reseteaEeprom();
  modeloActual=cargaDatosEeprom(255);

 // LCD config
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.print(txVer);
  display.setCursor(0,7);  
  display.print("(c) 2014");
  display.display();
  delay(2000);
  // ppm timer config
  pinMode(sigPin, OUTPUT);
  digitalWrite(sigPin, !onState);
  configTimer1();
}

void loop() {
  int i;
  int j=0;
  unsigned char tecla=0;
  int vBat;
  unsigned char valT;
  while(1) {
    vBat=analogRead(batPin);
    // read potentiometers
    readPots();
    readSwitches();
    
    // read keyboard value every 10th loop and store it
    // and set the values depending on the menu option
    displayReady=false;
    display.clearDisplay();
  if (pantalla==0) {
      // info screen
      unsigned char valBar;  
      display.setCursor(2,0);
      display.print("M: ");
    display.setCursor(30,0);
    display.print(modeloActual+1); 
      // throtle cut switch value
             // throtle cut
          if (bitRead(sw_status,0)==0) {
            display.setCursor(2, 57);
            display.print("TC");
          } else {
            display.setCursor(2, 57);
            display.print("  ");
          }
          // dual rates
          if (bitRead(sw_status,1)==0) {
             display.setCursor(45, 57);
            display.print("Rate: LO");
          } else {
             display.setCursor(45, 57);
             display.print("Rate: HI");
          }
      // batery Voltage
      display.setCursor(75, 0);
      display.print("Bat: ");  
      int voltajeBat=map(vBat,0,1023,0,100);
      display.setCursor(98, 0);
      display.print(voltajeBat);
      display.setCursor(120, 0);
      display.print("%");
    
          
      // draw the bars
      display.drawLine(64,9,64,42, WHITE);
      for (i=0;i<=4;i++) {
        // level bars
        valBar=pots[i]/11,5;
        display.drawRect(15,9+(i*8),98,3, WHITE);
        display.drawPixel(16+valBar,10+(i*8), WHITE);
        display.drawPixel(15+valBar,10+(i*8), WHITE);
        display.drawPixel(17+valBar,10+(i*8), WHITE);
        // servo reverse indicator
        if (bitRead(servoReversa, i)) {
          display.setCursor(8, 8+(i*8));
          display.print("R"); 
        } else {
          display.setCursor(8, 8+(i*8));
          display.print("N");      
        }
      }
    } 
    else {
      if (pantalla==1) {
         // main menu
         display.setCursor(0, 0);
         display.print(msgs[0]);
          for (i=1;i<=5;i++) {
              if (i==menuSubActual) {
              display.setCursor( 0, i*9);
              display.print("->");
              display.setCursor( 10, i*9);
              display.print(msgs[i]);
              } else {
              display.setCursor( 0, i*9);
              display.print("  ");
              display.setCursor( 10, i*9);
              display.print(msgs[i]);
              }
          }
      }

      if (pantalla==2) {
        if ( menuActual==1) {
          // servo reversing
          display.setCursor( 0, 0);
          display.print(msgs[menuActual]);
          for (i=0;i<=(CANALES-1);i++) {
            if (i==menuSubActual) {
              display.setCursor( 0, 8+i*8);
              display.print("->");                   
            } 
            else {
              display.setCursor( 0, 8+i*8);
              display.print("  ");                
            }
              display.setCursor( 10, 8+i*8);
            display.print("CH: ");
              display.setCursor( 22, 8+i*8);
            display.print(String(i+1));
            if (bitRead(servoReversa,i)) {
              display.setCursor( 26, 8+i*8);
              display.print(" - R");
            } 
            else {
              display.setCursor(  26, 8+i*8);
              display.print(" - N");
            }
          }
              display.setCursor( 55, 42);
          display.print("Mod: ");  
              display.setCursor( 75, 42);
          display.print(String(modeloActual+1));
        }

        if(menuActual==2) {
          // dual rates
          unsigned char contadorTemp=0;
          display.setCursor(0,0);
             display.print(msgs[menuActual]);
          for (i=0;i<=(CANALES-1);i++) {
            display.setCursor(0, 8+i*8);
            display.print("CH: ");
            display.setCursor(18, 8+i*8);
            display.print(String(i+1));
            if (menuSubActual==contadorTemp) {
              if (drSeleccion==contadorTemp) {
                display.setCursor(26, 8+i*8);
                   display.print("*");     
                 } 
              else {
                  display.setCursor(26, 8+i*8);
                   display.print(">");
              }
            }
          display.setCursor(30, 8+i*8);
               display.print("L:" ); 
               display.setCursor(42, 8+i*8);
               display.print(String(dual_rate_low[i]));
               contadorTemp++;               
               if (menuSubActual==contadorTemp) {
                 if (drSeleccion==contadorTemp) {
                 display.setCursor( 55, 8+i*8);
                   display.print("*");  
                 } else {
                   display.setCursor( 55, 8+i*8);
                   display.print(">");
                 }
               }
               display.setCursor(  60, 8+i*8);
               display.print("H:");
               display.setCursor(  70, 8+i*8);
               display.print(String(dual_rate_hi[i]));
               contadorTemp++;
          }
        }

        if (menuActual==3) {
          // model selection
           display.setCursor(  0, 0);
             display.print(msgs[menuActual]);
          for (i=0;i<=(MODELOS-1);i++) {
           display.setCursor(  8, 8+i*8);
                 display.print("Mod: ");
                 display.setCursor(  27, 8+i*8);
                 display.print(String(i+1) );
                 if (i==menuSubActual) {
                   display.setCursor(0, 8+i*8);
                    display.print("->" );                   
                 } else {
                   display.setCursor( 0, 8+i*8);
                    display.print("  ");                
                 }
                 
                 if (i==modeloActual) {
                   display.setCursor(35, 8+i*8);
                    display.print("*");
                 }
             }
          }
          
          
        if (menuActual==4) {
          // data save
          int eepromBase;
          eepromBase=numBytesPorModelo*modeloActual;
          unsigned char eepromPos =eepromBase;
          // actual model
          EEPROM.write(511,modeloActual);
          // servo reverse
          EEPROM.write(eepromPos, servoReversa);
          eepromPos++;
          // dual rates
          for (i=0;i<=CANALES;i++) {
            EEPROM.write(eepromPos, dual_rate_low[i]);
            eepromPos++;
            EEPROM.write(eepromPos, dual_rate_hi[i]);
            eepromPos++;
          }

          display.setCursor(  0, 20);
             display.print("Saving data for");
          display.setCursor(  0, 28);
             display.print("actual model:");
          display.setCursor(  0, 40);
             display.print(String(modeloActual+1));
          display.setCursor(  0, 42);
             display.print("...wait");
          pantalla--;
          menuActual=1;
          menuSubActual=1;
             display.display();
          delay(1000);
        }

        if (menuActual==5) {
          // gimbal calibration
          display.setCursor(  0, 0);
          display.print(msgs[menuActual]);
          display.display();
          delay(500);
          display.clearDisplay();
          for (i=0;i<=CANALES;i++) {
            calibracion[i][0]=512;
            calibracion[i][1]=512;
          }
          tecla=readKeys(); 
          while (tecla!=1) {
          display.clearDisplay();
          display.setCursor(  0, 0);
            display.print("Calibration");
            display.setCursor(  0, 8);
            display.print("Move the sitcks");
            display.setCursor(  0, 16);
            display.print("1: ");
            display.setCursor(20, 16);
            display.print(String(analogRead(inPots[0])));
            display.setCursor(  40, 16);
            display.print("2: ");
            display.setCursor(  60, 16);
            display.print(String(analogRead(inPots[1])));
            display.setCursor(  0, 24);
            display.print("3: ");
            display.setCursor(  20, 24);
            display.print(String(analogRead(inPots[2])));
            display.setCursor(  40, 24);
            display.print("4: ");
            display.setCursor(  60, 24);
            display.print(String(analogRead(inPots[3])));
            display.setCursor( 0, 32);
            display.print("5: ");
            display.setCursor( 20, 32);
            display.print(String(analogRead(inPots[4])));
            display.setCursor(   40, 32);
            display.print("6: ");
            display.setCursor(  60, 32);
            display.print(String(analogRead(inPots[5])));
          display.display();
            int lecturaTemporal;
            for (i=0;i<=(CANALES-1);i++) {
              lecturaTemporal=analogRead(inPots[i]);
              // min values
              if (lecturaTemporal<=calibracion[i][0]) {
                calibracion[i][0]=lecturaTemporal;
              }
              // max values
              if (lecturaTemporal>=calibracion[i][1]) {
                calibracion[i][1]=lecturaTemporal;
              }
              delay(10);
            }
            tecla=readKeys();
          }
          // save calibration data
          int posEeprom=0;
          for (i=0;i<=(CANALES-1);i++) {
            posEeprom=400+(i*4);
            EEPROMWriteInt(posEeprom, calibracion[i][0]); //min
            posEeprom+=2;
            EEPROMWriteInt(posEeprom, calibracion[i][1]); //max
          }
          display.clearDisplay();
          display.setCursor(  0, 20);
          display.print("Saving calibration");
          display.setCursor(  0, 28);
          display.print("data");
          display.setCursor(   0, 40);
          display.print("...wait");
          display.display();
          delay(1000);
          pantalla=0;
          menuActual=0;
          menuSubActual=0;
        }
      }

    }

    // screen update
    display.display();


    // read keyboard every 2 loops
    if (j>2) {
      tecla=readKeys(); 
      if (tecla==2) {
        if (pantalla<2) { 
          pantalla++; 
          menuActual=menuSubActual; 
          menuSubActual=0;
        } 
        else {
          // options for each menu
          if (menuActual==1) {
            // reversa de servos
            bitWrite(servoReversa, menuSubActual, !bitRead(servoReversa,menuSubActual));
          }
          if (menuActual==2) {
            // dual rates
            if (drSeleccion!=0xFF) {
              drSeleccion=0xFF;
            } 
            else {
              drSeleccion=menuSubActual;
            }
          }

          if (menuActual==3) {
            // model selection
            modeloActual=menuSubActual;
            // load data from eeprom
            EEPROM.write(511, modeloActual);
            cargaDatosEeprom(modeloActual);
            pantalla=0; 
            menuSubActual=0; 
            menuActual=0;
          }
        }
      }

      if (tecla==3) {
        switch (menuActual) {
        case 2:
          if (drSeleccion==0xFF) {
            if (menuSubActual<(CANALES*2)) { 
              menuSubActual++; 
              if (pantalla==0) {
                pantalla++; 
              }
            }
          } 
          else {
            if ((drSeleccion%2)==0) {
              if (dual_rate_low[drSeleccion/2]>0) { 
                dual_rate_low[drSeleccion/2]--;  
              }    
            } 
            else {
              if (dual_rate_hi[drSeleccion/2]>0) { 
                dual_rate_hi[drSeleccion/2]--;  
              } 
            }
          }
          break;
        default: 
          if (menuSubActual<6) { 
            menuSubActual++; 
            if (pantalla==0) {
              pantalla++; 
            }
          }
          break;
        }   

      }

      if (tecla==1) {
        switch (menuActual) {
        case 2:
          if (drSeleccion==0xFF) {
            if (menuSubActual==0) { 
              pantalla--; 
              menuSubActual=1; 
              menuActual=0;
            } 
            else { 
              menuSubActual--; 
            } 
          } 
          else {
            if ((drSeleccion%2)==0) {
              if (dual_rate_low[drSeleccion/2]<100) { 
                dual_rate_low[drSeleccion/2]++;  
              }
            } 
            else {
              if (dual_rate_hi[drSeleccion/2]<100) { 
                dual_rate_hi[drSeleccion/2]++;  
              } 
            }
          }
          break;
        default:
          if (menuSubActual>0) {
            menuSubActual--; 
          } 
          else {
            if (pantalla>0) { 
              pantalla--; 
              menuSubActual=1; 
              menuActual=0;
            }
          } 
          break;
        }
      }

      j=0;
    }
    j++;

  }
}

void readPots() {
  unsigned char i,j;
  int temporalPots[CANALES];
  for (i=0;i<=(CANALES-1);i++) {
    // read the pots     
    temporalPots[i]=analogRead(inPots[i]);
    // calibration mapping
    pots[i]=map(temporalPots[i],calibracion[i][0], calibracion[i][1], 0, 1023);
    // servo reversing
    if (bitRead(servoReversa,i)==1) {
      pots[i]=1023-pots[i]; 
    }

    // Throtle cut
    if (i==canalTh && bitRead(sw_status,0)==0) {
      // TC activado
      pots[i]=0;
    }

    // dual rates
    if (bitRead(sw_status,1)==0) {
      // low, rates
      pots[i]=ajusteDR(pots[i],dual_rate_low[i],i,canalTh);
    } 
    else {
      // hi rates 
      pots[i]=ajusteDR(pots[i],dual_rate_hi[i],i,canalTh);
    }  
    // map values to PPM
    ppm[i]=map(pots[i],potMin, potMax, ppmMin, ppmMax);
  }
}

void readSwitches() {
  // read switches and set into the sw_status var
  if (digitalRead(swTC)==HIGH) {
    bitWrite(sw_status,0,1);
  } 
  else {
    bitWrite(sw_status,0,0);
  }
  if (digitalRead(swDR)==HIGH) {
    bitWrite(sw_status,1,1);
  } 
  else {
    bitWrite(sw_status,1,0);
  }
}

unsigned char readKeys() {
  unsigned char salida;  
  salida = 0;
  if (digitalRead(4)==0) salida=3;
  if (digitalRead(2)==0) salida=2;
  if (digitalRead(3)==0) salida=1;
  // read analog keyboard
  delay(25);
  return salida;
}

int  freeRam () {
  // returns free ram in avr chip
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

unsigned char cargaDatosEeprom(unsigned char mod) {
  // load data from eeprom, for selected model
  int eepromBase;
  unsigned char i;
  if (mod=255) {
    mod=EEPROM.read(511);
  } 

  eepromBase=numBytesPorModelo*mod;
  unsigned char eepromPos=eepromBase;
  // servo reversing
  servoReversa=EEPROM.read(eepromPos);
  eepromPos++;
  // dual rates
  for (i=0;i<=CANALES-1;i++) {
    dual_rate_low[i]=EEPROM.read(eepromPos);
    eepromPos++;
    dual_rate_hi[i]=EEPROM.read(eepromPos);
    eepromPos++;
  }
  int posEeprom;
  for (i=0;i<=(CANALES-1);i++) {
    posEeprom=400+(i*4);
    calibracion[i][0]=EEPROMReadInt(posEeprom); //minimo
    posEeprom+=2;
    calibracion[i][1]=EEPROMReadInt(posEeprom); //maximo
  }

  return mod;
}

unsigned char reseteaEeprom() {
  // erases eeprom, just for checking values (unused now)
  int eepromBase, eepromPos;
  unsigned char i,j;
  EEPROM.write(511,0);
  for (j=0;j<=CANALES-1;j++) {
    eepromPos=numBytesPorModelo*j;
    EEPROM.write(eepromPos,0x00);
    eepromPos++;
    for (i=0;i<=CANALES-1;i++) {
      EEPROM.write(eepromPos,75);
      eepromPos++;
      EEPROM.write(eepromPos,100);
      eepromPos++;

    }
  }      
}


int ajusteDR(int valor, float dr, unsigned char canal, unsigned char canTh) {
  // dual rate calc
  int salida,temp;
  float mult;
  mult=dr;
  if (canal==canalTh) {
    salida=(int)valor*mult/100;  
  } 
  else {
    temp=valor-512;
    salida=(int)((temp*mult/100)+512);

  }
  salida=constrain(salida,0,1023);
  return salida;
}


void EEPROMWriteInt(int p_address, int p_value) {
  // write a 16bit value in eeprom
  byte Byte1 = ((p_value >> 0) & 0xFF);
  byte Byte2 = ((p_value >> 8) & 0xFF);
  EEPROM.write(p_address, Byte1);
  EEPROM.write(p_address + 1, Byte2);
}

int EEPROMReadInt(int p_address) {
  // read a 16 bit value in eeprom
  byte Byte1 = EEPROM.read(p_address);
  byte Byte2 = EEPROM.read(p_address + 1);
  long firstTwoBytes = ((Byte1 << 0) & 0xFF) + ((Byte2 << 8) & 0xFF00);
  return (firstTwoBytes);
}





love your setup can i get some help with my setup
papo is offline Find More Posts by papo
Reply With Quote
Old Mar 24, 2015, 08:13 AM
papo is offline
Find More Posts by papo
Registered User
New York Ny/Newark Downtown Manhatt, New York, United States
Joined Dec 2003
121 Posts
almost ready for tx setup

finished the fpv side of radio
NEED HELP NEED HELP with arduino micro pro
papo is offline Find More Posts by papo
Last edited by papo; Mar 24, 2015 at 08:19 AM.
Reply With Quote
Old Mar 25, 2015, 12:32 AM
Expertsetup is offline
Find More Posts by Expertsetup
Registered User
Joined Dec 2014
9 Posts
Quote:
Originally Posted by bianchifan View Post
And now my problem, I cannot compile ardutx_v1_3.
The library do not work, wrong data types, Ubuntu (x64, 1.05) as well as Win7 (x64, 1.6).

It seems that the source (Nokia lib) depends on a special (old) version.
Hello, change the file DefaultFonts.c in the LCD library at the top by adding 'const' to line three like this:

Code:
#if defined(__AVR__)
	#include <avr/pgmspace.h>
	#define fontdatatype const uint8_t
Then it should compile under the latest arduino version (1.6.1)
Expertsetup is offline Find More Posts by Expertsetup
Reply With Quote
Old Mar 25, 2015, 12:37 AM
Expertsetup is offline
Find More Posts by Expertsetup
Registered User
Joined Dec 2014
9 Posts
Quote:
Originally Posted by papo View Post
finished the fpv side of radio
NEED HELP NEED HELP with arduino micro pro
Looks very cool, what do you need help with? This project works great for a low cost DIY controller. While this works as a great little controller it will also need a transmitter module that accepts PPM signal input. You can easily make a TX module if you search this forum Midelic has a nice module that I use with this controller here:

DIY Multiprotocol TX
Expertsetup is offline Find More Posts by Expertsetup
Reply With Quote
Old Mar 25, 2015, 12:45 AM
Expertsetup is offline
Find More Posts by Expertsetup
Registered User
Joined Dec 2014
9 Posts
OK so a quick and dirty solution for transmitter and RX can use this guide to get up and running:

Cheap-ass Transmitter & PPM RX generic solution

or you can get some telemetry by extending that system:

MultiWii 2.3 NRF24L01 integrated Transmitter source included
Expertsetup is offline Find More Posts by Expertsetup
Reply With Quote
Old Apr 27, 2015, 02:02 PM
franko_ is offline
Find More Posts by franko_
Home of Ebbelwoi
Germany, HE, Frankfurt
Joined Mar 2013
148 Posts
Hi,

i want to build my own tx, but imīm a little bit confused regarding schematics.
What i want to use:
Crius i2C Oled with sketch from mrheat and 5/6 channels, i see in first post 5 switches. which resistor value is right?

http://123d.circuits.io/circuits/745...v0-9#schematic

Is that the matching circuit with right resistors?
R1-R4 are the gimbals.. right?
SW1 to SW5 doing what? top/down/left/right/TR ?
The pot R6, what is the function?

Hope someone can help me here....

BR
Frank
franko_ is offline Find More Posts by franko_
Reply With Quote
Old May 23, 2015, 05:49 PM
elewon is offline
Find More Posts by elewon
Registered User
elewon's Avatar
United States, CA, Sacramento
Joined Feb 2013
346 Posts
Guys, just came across this thread. If you are looking for an easy to build DIY Tx, I'd recommend MEGA2580 with OpenTx. Here's a thread I started with lot of information about how to do it: http://www.rcgroups.com/forums/showthread.php?t=2406337
elewon is offline Find More Posts by elewon
Reply With Quote
Old May 31, 2015, 08:12 AM
franko_ is offline
Find More Posts by franko_
Home of Ebbelwoi
Germany, HE, Frankfurt
Joined Mar 2013
148 Posts
Quote:
Originally Posted by elewon View Post
Guys, just came across this thread. If you are looking for an easy to build DIY Tx, I'd recommend MEGA2580 with OpenTx. Here's a thread I started with lot of information about how to do it: http://www.rcgroups.com/forums/showthread.php?t=2406337
thx @Elewon,

itīs a good alternative, but not as easy to build as an Arduino Transmitter.
Have a Crius AIO lying around... hmm
franko_ is offline Find More Posts by franko_
Reply With Quote


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Sold Airtronics RD 6000 6CH Computer Radio w/ extras hobbyfun100 Aircraft - General - Radio Equipment (FS/W) 2 Feb 06, 2013 07:17 AM
Discussion need help with HobbyKing 2.4Ghz 6Ch Tx & Rx V2 berts Beginner Training Area (Aircraft-Electric) 2 Jan 26, 2013 10:58 PM
Sold Airtronics RD 6000 6CH Computer Radio w/ extras hobbyfun100 Aircraft - General - Radio Equipment (FS/W) 1 Jan 19, 2013 12:37 PM
Discussion Arduino -> FASST TX module ---> receiver codeforge DIY Electronics 1 Jan 02, 2013 12:42 PM
Help! Can't get Hobbyking 6ch tx to work with computer doh2doh Radios 2 Jun 14, 2012 11:07 AM