FPV groundstation project

Hi.
So im going to need alot of help here in the future.

Not been that long in to arduino so im kind of a newbie.

Im building a groundstation for my FPV videosystem.

There are alot of stuff thats going to be controlled by the arduino and some stuff is only going to get printed on to my display.

In this case I have a 4 Position 15 Pin Rotary Switch thats connected with different resistors to a analog input. Everything looks good in the serial monitor and it gives me different values on the screen when switching it to the different positions.

So, the values are:
220-230
20-100
1000-1020
500-600

on the switch from 1 to 4.

When having the switch set to position 1 I get readings from 220 to 230, so when the value is between those two numbers I want my screen to print "Video output: 1.2ghz".

If the value is between 20 and 100 I want it to print "Video output: 5.8ghz"
and so on.

How to do this? I have spend so many hours trying to get it to work so I dont think my eyes will work soon =/

This is the code that I have written so far:

//Peter Landins Groundstation
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
int sensePin =0;

LiquidCrystal_I2C lcd(0x27,20,4); 

void setup()
{

   
  lcd.init(); 
    lcd.backlight();
    lcd.setCursor(2, 0);
    lcd.print("FPV Groundstation");    
    lcd.setCursor(2,2);           
    lcd.print("Version 1.0");
    lcd.setCursor(2,3);
    lcd.print("Peter Landin");
    delay(3000);    
}
void loop()
{
   
  int val = analogRead(sensePin);
    if(val >= 200 && <= 250); //First input on videoswitcher
    lcd.init(); 
    lcd.backlight();
    lcd.setCursor(2, 0);
    lcd.print("Video input: 1.2gHz");
  

}

So if anyone can give me a push on this I would be gratefull!
Thanx

Landin81:
In this case I have a 4 Position 15 Pin Rotary Switch thats connected with different resistors to a analog input. Everything looks good in the serial monitor and it gives me different values on the screen when switching it to the different positions.

So, the values are:
220-230
20-100
1000-1020
500-600

on the switch from 1 to 4.

When having the switch set to position 1 I get readings from 220 to 230, so when the value is between those two numbers I want my screen to print "Video output: 1.2ghz".

If the value is between 20 and 100 I want it to print "Video output: 5.8ghz"
and so on.

How to do this? I have spend so many hours trying to get it to work so I dont think my eyes will work soon =/

This is the code that I have written so far:

//Peter Landins Groundstation

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int sensePin =0;

LiquidCrystal_I2C lcd(0x27,20,4);

void setup()
{

lcd.init();
   lcd.backlight();
   lcd.setCursor(2, 0);
   lcd.print("FPV Groundstation");    
   lcd.setCursor(2,2);          
   lcd.print("Version 1.0");
   lcd.setCursor(2,3);
   lcd.print("Peter Landin");
   delay(3000);    
}
void loop()
{
 
 int val = analogRead(sensePin);
   if(val >= 200 && <= 250); //First input on videoswitcher
   lcd.init();
   lcd.backlight();
   lcd.setCursor(2, 0);
   lcd.print("Video input: 1.2gHz");

}





So if anyone can give me a push on this I would be gratefull!
Thanx

Ok,
the problem you are encountering is Visual Basic Verses C++.

void loop()
{
   
  int val = analogRead(sensePin);     // this line is correct.
    if(val >= 200 && <= 250); //First input on videoswitcher,   this one does nothing.
    lcd.init(); 
    lcd.backlight();
    lcd.setCursor(2, 0);
    lcd.print("Video input: 1.2gHz");
  

}

// try this code

void loop()
{
   
  int val = analogRead(sensePin);     // this line is correct.
    if(val >= 200 && <= 250){   // did you see I made a compound statement?
                  //First input on videoswitcher,   this one does nothing.
      // lcd.init();  did not need, setup() already initialized the LCD 
      // lcd.backlight();  did not need setup() already turned on the back light

      lcd.setCursor(2, 0);
      lcd.print("Video input: 1.2gHz");
      }  // end of compound if Statement

}

// how about this code

void loop(){
  int val = analogRead(sensePin);     
  lcd.setCursor(2,0);
  if (val < 150) {  
     lcd.print("Video Output 5.8gHz");     
     }
   else if (val < 250) {
     lcd.print("Video Output 1.2gHz");     
     }
   else if (val < 750 ) {
     lcd.print("Video unknown <750 ");
     }
   else lcd.print("Video unknown ");
}

indenting does not mean anything in C++ it is just a white space, the Curly brackets are used to identify a compound statement.

if (logical_statement); // means if logical_statement evaluates to a value not zero then ; (nothing)

if(logical_statement){  // means if ... then execute everything between the pair {} of curly braces
   // this one
   // and this one
  }  // until here!

Chuck.

void loop()
{

int val = analogRead(sensePin);
if(val >= 200 && val <= 250)// ; <- DELETE //First input on videoswitcher
lcd.init();
lcd.backlight();
lcd.setCursor(2, 0);
lcd.print("Video input: 1.2gHz");

}

chucktodd:
Chuck

Thanx alot! That really helped!
So I was mixing in c++?

If I want another input to show up on the next row on the display, And than yet another on the third?
Is that very hard to do?

I want to use the display as much there is for the information I need.
I have more pins to use on the nano so we dont need to use the "VAL"

Can I just do a "VAL2" and a new loop for it and do the same with the values?
Or do they have to be implemented in to the existing code?

I also have a relaycard with two relays and a volt/currentsensor.
On the first row on the display, I want it to show Mvolt (as in Mainvolt) Bvolt (Backupbattery) and Cur: (as in current draw)
The main and backup battery will be connected to the two relays, if main volt drops under 10.5v it should switch on relay two and .5 seconds later the main battery relay should go off. When backup battery is driving the system, I want a little beeper to beep every 30 seconds and if its posible the Bvolt start to blink in the display.

row three on the display: Video inputs as the code above.

I know its alot of code, but all help is welcome.

Best regards Peter

The simple way to work with the values you have is to start at the top and work down (or the bottom and work up)

if ( val > 650) {
   //do A
}
else if (val > 250) {
   // do B
}
else if (val > 120) {
   // do C
}
else {
   // do D
}

...R

Robin2:
The simple way to work with the values you have is to start at the top and work down (or the bottom and work up)

if ( val > 650) {

//do A
}
else if (val > 250) {
  // do B
}
else if (val > 120) {
  // do C
}
else {
  // do D
}




...R

So I can put the different rows of text in to the same loop of code?
If val1 > 250)
do A
else if (val1 >500)
doB
if Val2 > 250)
do c

not a legit code but for example..
etc?

So I can put the different rows of text in to the same loop of code?

Your terminology leaves a lot to be desired. "Rows of text" seems to mean lines of code. "loop of code" means nothing.

You appear not to have noted the "start at the top and work down (or the bottom and work up)" part of Robin2's post.

PaulS:
Your terminology leaves a lot to be desired. "Rows of text" seems to mean lines of code. "loop of code" means nothing.

You appear not to have noted the "start at the top and work down (or the bottom and work up)" part of Robin2's post.

Rows of text = On LCD rows of text.

Loop of code = In the same void loop.

=)

I want to have more text on the same "Lcdpage" from another sensepin to show up.
Would it be inbedded in the same code, or can I write it over the existing code?

Landin81:
I want to have more text on the same "Lcdpage" from another sensepin to show up.
Would it be inbedded in the same code, or can I write it over the existing code?

Your example in Reply #5 is not consistent with my suggestion.

Can you give us a more extensive example of what you want to do. Taking it in little pieces just leaves too much room for confusion.

Have a look at planning and implementing a program

...R

Robin2:
Your example in Reply #5 is not consistent with my suggestion.

Can you give us a more extensive example of what you want to do. Taking it in little pieces just leaves too much room for confusion.

Have a look at planning and implementing a program

...R

Ok, so this is the basics in the setup.

I have a case with a 9" screen that my flightvideo is going to show my flightvideo.

In the case I will have two batteries, one main battery and one backup.

I will have a DVR thats record my flight video and instruments.
One aux input, one input for 1.2ghz video, one for 5.8ghz and one video out. Also a 5.8ghz transmitter so that I can run my videogoggles wireless.

There will be a volt and currentsensor connected between the wires that comes out from the relays on the other side of the batteries, when the main battery is dropping down to under 10.5v I want the backup-relay to get activated, .5 seconds after its on I want the mainbattery-relay to switch of, just so I dont loose any power to my system.

When the backup battery is on, I want a buzzer to start beeping every 30 seconds.

On the LCD I want it to show Mvolt as in main volt, and after that Bvolt as in backupvolt, and last C if there is enaugh room for current.

on the third row on the display I want to show the video input as in the text above, thats working nice now.

thats all I want to have to start with, later on I will have it to show RSSI input from the 1.2 and 5.8 diversity system, on another page on the LCD, but thats will be in the future =)

Landin81:
Ok, so this is the basics in the setup.

Sorry, but that is not what I meant by "a more extensive example of what you want to do"

I was hoping you would extend the pseudo code you showed in Reply #5 to take account of your comments in Reply #7 so that I could understand the code you are trying to write.

...R

Landin81:
Thanx alot! That really helped!
So I was mixing in c++?

If I want another input to show up on the next row on the display, And than yet another on the third?
Is that very hard to do?

I want to use the display as much there is for the information I need.
I have more pins to use on the nano so we dont need to use the "VAL"

Can I just do a "VAL2" and a new loop for it and do the same with the values?
Or do they have to be implemented in to the existing code?

I also have a relaycard with two relays and a volt/currentsensor.
On the first row on the display, I want it to show Mvolt (as in Mainvolt) Bvolt (Backupbattery) and Cur: (as in current draw)
The main and backup battery will be connected to the two relays, if main volt drops under 10.5v it should switch on relay two and .5 seconds later the main battery relay should go off. When backup battery is driving the system, I want a little beeper to beep every 30 seconds and if its posible the Bvolt start to blink in the display.

row three on the display: Video inputs as the code above.

I know its alot of code, but all help is welcome.

Best regards Peter

Ok Peter,
Here is my interpretation of what you wrote.

  • You want to use multiple pins as inputs to measure something

  • You want to use multiple pins as output to control relays

  • You want to display multiple messages on the LCD at the same time.

  • You want to have multiple battery that can power your device

My advice, break you program into multiple blocks(function), have each function do one thing. It would help me if you would post a schematic of your circuit. Having an actual hardware description to reference coding examples against can avoid mistakes.

One questionable item in your circuit description:

When the prime battery falls below 'x' Volts, connect secondary battery, wait 30 seconds, then disconnect prime battery.

Depending on your circuit, you could overload the secondary battery. If the Primary battery is 'dead' and you attach a fully charged secondary battery, the 'dead' primary battery will discharge the secondary battery at a high current. Unless your connection circuit is designed to disallow this recharge current. (a posted schematic would answer my question).

To answer question 1, Yes you can use multiple inputs. Be aware that the Arduino has only one Analog to Digital Converter (ADC), it has multiple inputs (A0..A5) that are switched between when you call analogRead(analogPIN); It takes a little while for the voltage on the ADC to stabilize after the switching event, good practice is to average multiple readings:

unsigned long totalReadings=0;
for(uint8_t i=0;i<4;i++){
  totalReadings += analogRead(analogPin);
  }
uint16_t reading = totalReadings/4;

Displaying multiple messages on the LCD is easy. Just realize you are going to have to position the cursor before every message display event, also you will have to overwrite what is on the display with space characters to erase the previous message.

If you are using a 20x4 LCD, you can call setCursor(0,0) to setCursor(19,3) to select where the next print() statement will display. to blink text on the screen, you have to erase that area of the screen, wait a short time, then re-print your message.

If your circuit can handle a dead battery and a fully charged cross connected the 30second switch time is quite easy;

void setup(){
pinMode(batteryOneRelayControlPin,OUTPUT);
digitalWrite(batteryOneRealyControlPin,HIGH); // if your ciruit is wired this way?
pinMode(batteryTwoRelayControlPin,OUTPUT);
digitalWrite(batteryTwoRealyControlPin,LOW); // if your ciruit is wired this way?

pinMode(senseOnePin,INPUT);
pinMode(senseTwoPin,INPUT);
}

// this is really Bad Coding, but it works.  The Delay stops the arduino from doing anything else
// until the delay has completed, if another switch is activated it would not be acted upon until
// the delay has completed.

void switchBatteries(){ // switch decision has already been decided
digitalWrite(batteryTwoRelayControlPin,HIGH);
delay(30000);
digitalWrite(batteryOneRelayControlPin,LOW);
}

// a better coding would be this
enum POWERSTATES {
   powerOff,                        // impossible, arduino can't run program if it has not power!
   powerPrime,                     // on primary battery
   powerToPrime,                 // switch back to primary battery ?
   powerSecondary,              // on backup battery
   PowerToSecondary            // transferring to backup battery
};

POWERSTATES power=powerOff;

void setup(){
pinMode(batteryOneRelayControlPin,OUTPUT);
digitalWrite(batteryOneRealyControlPin,HIGH); // if your circuit is wired this way?
pinMode(batteryTwoRelayControlPin,OUTPUT);
digitalWrite(batteryTwoRealyControlPin,LOW); // if your circuit is wired this way?

power=powerPrime;
}

unsigned long timeOut=0; // initialize a timeout counter for delay events.
bool blink=false;              // control for blink on, off

void checkPower(){  // read batterySense, switch to Backup if necessary
unsigned long temp=0;
for(uint8_t i=0;i<4;i++){  // create average battery reading
  temp = temp + analogRead(batterySense);
  }
uint16_t voltage=temp /4;   // average battery reading

char printBuff[21];         // display a fixed length string on the lcd
uint8_t len=sprintf(printbuff,"bat=%d",voltage);
for(uint8_t i =len; i<batFieldLen;i++){
  printbuff[i]=' '; // blank out rest of voltage field
  }
printbuff[batFieldLen]=0;  // mark end of string
LCD.setCursor(row,col);
LCD.print(printbuff); // display battery voltage 

switch(power){  // depending on what power source, the choices are different
  case powerPrime: 
    if(voltage < lowVoltThreshold){ // are running off prime battery, and it is low!
      timeout = millis() + 30000; // mark the start of the switch stage.
      digitalWrite(batteryTwoRelayControlPin,HIGH);  // turn on secondary battery
      power = powerToSecondary;
      LCD.setCursor(primeBatteryRow,primeBatteryCol);
      LCD.print("  DEAD! ");
      LCD.setCursor(secondaryBatteryRow,decondaryBatteryCol);
      LCD.print("  Switching! ");
      }
    break;

  case powerToSecondary : // in process to transfer to secondary battery
    if(millis()> timeout) {
      digitalWrite(batteryOneRelayControlPin,LOW); // turn off Primary Battery
      power = powerSecondary;
      LCD.setCursor(secondaryBatteryRow,decondaryBatteryCol);
      LCD.print("  OnLine!  ");
      }
    break;
  case powerSecondary : // on Backup battery
    if(timeout>millis()){ // flash Secondary Battery Status
      LCD.setCursor(secondaryBatteryRow,decondaryBatteryCol);
      if(blink) {
        LCD.print("              ");
        blink = false;
        }
      else{
        LCD.print("  OnLine!  ");
        blink = true;
        }
      timeOut = millis() +500; // flash every 1/2 second
      }
   default : ; // handle other cases, 
  }
}  

void loop(){

  checkPower();  // need to check power at least every 1/2 second, more is better.

  //  do other stuff
}

This code is untest, but the logic will work.

Chuck.

So Im trying to answer with red text in your quote.

chucktodd:
Ok Peter,
Here is my interpretation of what you wrote.

  • You want to use multiple pins as inputs to measure something

  • You want to use multiple pins as output to control relays

  • You want to display multiple messages on the LCD at the same time.

  • You want to have multiple battery that can power your device

Yes thats correct above.

My advice, break you program into multiple blocks(function), have each function do one thing. It would help me if you would post a schematic of your circuit. Having an actual hardware description to reference coding examples against can avoid mistakes.
Ok, So the code for the input dont have to be in the same section? I can use the code that you wrote, and than write new code under that code and still get everything to show up on the screen?

One questionable item in your circuit description:

When the prime battery falls below 'x' Volts, connect secondary battery, wait 30 seconds, then disconnect prime battery. No, that not what I wrote =)
When the primary voltage drops below "x" volts, connect secondary battery, wait 0.5seconds and then disconnect prime battery, and when on the secondary battery, turn on buzzer to warn me every 30 seconds =)

Depending on your circuit, you could overload the secondary battery. If the Primary battery is 'dead' and you attach a fully charged secondary battery, the 'dead' primary battery will discharge the secondary battery at a high current. Unless your connection circuit is designed to disallow this recharge current. (a posted schematic would answer my question).

To answer question 1, Yes you can use multiple inputs. Be aware that the Arduino has only one Analog to Digital Converter (ADC), it has multiple inputs (A0..A5) that are switched between when you call analogRead(analogPIN); It takes a little while for the voltage on the ADC to stabilize after the switching event, good practice is to average multiple readings:

unsigned long totalReadings=0;

for(uint8_t i=0;i<4;i++){
totalReadings += analogRead(analogPin);
}
uint16_t reading = totalReadings/4;




Displaying multiple messages on the LCD is easy. Just realize you are going to have to position the cursor before every message display event, also you will have to overwrite what is on the display with space characters to erase the previous message.

If you are using a 20x4 LCD, you can call setCursor(0,0) to setCursor(19,3) to select where the next print() statement will display. to blink text on the screen, you have to erase that area of the screen, wait a short time, then re-print your message.

If your circuit can handle a dead battery and a fully charged cross connected the 30second switch time is quite easy;



void setup(){
pinMode(batteryOneRelayControlPin,OUTPUT);
digitalWrite(batteryOneRealyControlPin,HIGH); // if your ciruit is wired this way?
pinMode(batteryTwoRelayControlPin,OUTPUT);
digitalWrite(batteryTwoRealyControlPin,LOW); // if your ciruit is wired this way?

pinMode(senseOnePin,INPUT);
pinMode(senseTwoPin,INPUT);
}

// this is really Bad Coding, but it works. The Delay stops the arduino from doing anything else
// until the delay has completed, if another switch is activated it would not be acted upon until
// the delay has completed.

void switchBatteries(){ // switch decision has already been decided
digitalWrite(batteryTwoRelayControlPin,HIGH);
delay(30000);
digitalWrite(batteryOneRelayControlPin,LOW);
}

// a better coding would be this
enum POWERSTATES {
powerOff, // impossible, arduino can't run program if it has not power!
powerPrime, // on primary battery
powerToPrime, // switch back to primary battery ?
powerSecondary, // on backup battery
PowerToSecondary // transferring to backup battery
};

POWERSTATES power=powerOff;

void setup(){
pinMode(batteryOneRelayControlPin,OUTPUT);
digitalWrite(batteryOneRealyControlPin,HIGH); // if your circuit is wired this way?
pinMode(batteryTwoRelayControlPin,OUTPUT);
digitalWrite(batteryTwoRealyControlPin,LOW); // if your circuit is wired this way?

power=powerPrime;
}

unsigned long timeOut=0; // initialize a timeout counter for delay events.
bool blink=false; // control for blink on, off

void checkPower(){ // read batterySense, switch to Backup if necessary
unsigned long temp=0;
for(uint8_t i=0;i<4;i++){ // create average battery reading
temp = temp + analogRead(batterySense);
}
uint16_t voltage=temp /4; // average battery reading

char printBuff[21]; // display a fixed length string on the lcd
uint8_t len=sprintf(printbuff,"bat=%d",voltage);
for(uint8_t i =len; i<batFieldLen;i++){
printbuff[i]=' '; // blank out rest of voltage field
}
printbuff[batFieldLen]=0; // mark end of string
LCD.setCursor(row,col);
LCD.print(printbuff); // display battery voltage

switch(power){ // depending on what power source, the choices are different
case powerPrime:
if(voltage < lowVoltThreshold){ // are running off prime battery, and it is low!
timeout = millis() + 30000; // mark the start of the switch stage.
digitalWrite(batteryTwoRelayControlPin,HIGH); // turn on secondary battery
power = powerToSecondary;
LCD.setCursor(primeBatteryRow,primeBatteryCol);
LCD.print(" DEAD! ");
LCD.setCursor(secondaryBatteryRow,decondaryBatteryCol);
LCD.print(" Switching! ");
}
break;

case powerToSecondary : // in process to transfer to secondary battery
if(millis()> timeout) {
digitalWrite(batteryOneRelayControlPin,LOW); // turn off Primary Battery
power = powerSecondary;
LCD.setCursor(secondaryBatteryRow,decondaryBatteryCol);
LCD.print(" OnLine! ");
}
break;
case powerSecondary : // on Backup battery
if(timeout>millis()){ // flash Secondary Battery Status
LCD.setCursor(secondaryBatteryRow,decondaryBatteryCol);
if(blink) {
LCD.print(" ");
blink = false;
}
else{
LCD.print(" OnLine! ");
blink = true;
}
timeOut = millis() +500; // flash every 1/2 second
}
default : ; // handle other cases,
}
}

void loop(){

checkPower(); // need to check power at least every 1/2 second, more is better.

// do other stuff
}




This code is untest, but the logic will work.

Chuck.

Thanks for the code, I have not yet read it, but I will spend some time to try to learn from it together with a cup of coffee =)

I will try to paint a schematic for you, this is the relays, buttons and current/voltmeter I have.

http://www.ebay.com/itm/251969102131?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

http://www.ebay.com/itm/141625778140?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

So here is a picture printed out of my head.
Just a basic sketch, hope you see what I see =)

The positive and negative is going to be hooked up to some switches that can run monitor, receivers, and more stuff.

So to start the device, I thinking of just have a pushbutton from mainbattery that gives my Ubec power and turn arduino on and switch the relay on. Even if there is a bad mainbattery it will only be under 10.5v and be able to give ubec power to start up the relays, if the arduino sense that mainbattery is bad it will switch on the backup anyway.

Are you with me? =)

Im bumping this up. still need help with this project =)

=/

I don't know if you are expecting any response from me, but I have not seen any follow-up to my Reply #10.

...R

Robin2:
I don't know if you are expecting any response from me, but I have not seen any follow-up to my Reply #10.

...R

Well, I thought the explanation would cover that. =)

I dont know what more you want to have in the code, its all I can think of that I have write.

I just wanted to know how to get several readings from my sensors on the same lcd "page", show volt, main and backup, show also amere, and last of all video input. =)