Any C programmers on here?

Dansin

Registered user
Joined
May 4, 2007
Messages
2,957
Reaction score
0
Location
Ombersley
For use with an arduino, I need help with a menu/submenu sketch. If anyone has a clue then I'll post up the sketch. :thumb2
 
I used to do a lot of c and c++ programming (it's basically just arguing with yourself in ever decreasing circles :D ), and I know what an arduino module is, but I have absolutely no idea how to link the two together.

So consider this just as a :bounce1 :thumb2

PS there are almost certainly a hundred nerdy forums specifically devoted to arduino littlebits......I bet they slag off raspberry pi owners as much as airhead riders slag off WC owners :D
 
I used to do a lot of c and c++ programming (it's basically just arguing with yourself in ever decreasing circles :D ), and I know what an arduino module is, but I have absolutely no idea how to link the two together.

So consider this just as a :bounce1 :thumb2

PS there are almost certainly a hundred nerdy forums specifically devoted to arduino littlebits......I bet they slag off raspberry pi owners as much as airhead riders slag off WC owners :D

I'll post it up. You never know, you may have the answer straight away!

I've tried on the nerdy forums but no luck so far.

I think there is a section for this shite, so fuck off there then innit.

Att is of course correct. If required, can a mod please move this to the IT section?
 
Code is below. Hardware is an arduino, a GPS module, a seven segment display and a button. The arduino interrogates the GPS for a data string and then outputs the result to the display. Currently the menu scrolls 1, 2, 3, 4, 1 etc. The four things currently displayed are HEADING, MPH, KMPH, TIME. It's going to be used as a CAP repeater without the need for a separate GPS/satnav.

3 things I want to achieve:-

Have SPEED selectable between MPH or KMPH rather than displaying both.

Have BRIGHTNESS selectable in BRIGHT, NORMAL and DIM. Rather than having another menu item I want to do that when TIME is displayed.

Store the chosen settings on the Eeprom of the arduino so that they're remembered the next time the unit is powered up.

There are ways to achieve the submenu routines with a single button using a long press etc., but for simplicity and ease of use on the road, I want to use a second button.

I'm guessing the menu structure will be something like:-

Main menu

HEADING

SPEED - submenu - MPH, KMPH

TIME - submenu - BRIGHT, NORMAL, DIM

The mph/kmph bits are fairly obvious. The brightness settings will be achieved by
Code:
matrix.setBrightness(15);
with 15 being brightest.

Edit:- Button one will scroll the main menu items and button will scroll the submenu items.

It's working as is on a breadboard.

cf9bc3be2d027f52239c35caa9851cf3_zps98f8946c.jpg


The case is designed and away being 3D printed (although I'll need to cut another hole for the second button).

CAP_zps6323f378.jpg


Code:
#include <Bounce2.h>
#include <Adafruit_LEDBackpack.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

int Heading;
int Mph;
int Kph;
int Time;

#define BUTTON_PIN 2

Bounce  debouncer  = Bounce();

Adafruit_7segment matrix = Adafruit_7segment();

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;

SoftwareSerial ss(RXPin, TXPin);

unsigned long last = 0UL;

byte menu = 1;

void buttonState(){
      while (debouncer.update()) {
      if (debouncer.read() == HIGH)
      menu++;
      if (menu>4) menu = 1;
      matrix.clear();
        }
}        
    void condition1()
    {
      if (gps.course.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay(); 
      }
      else
      {
        Heading = (gps.course.deg());
        matrix.print(Heading);
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDisplay();
        Serial.println("Heading ") & Serial.println(gps.course.deg()); 
       }
    }
    
    void condition2()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay();     
      }
    else
      {
        Mph = (gps.speed.mph());
        matrix.print(Mph);
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDisplay();
        Serial.println("Mph ") & Serial.println(gps.speed.mph());  
       }
     }
    
    void condition3()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {      
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDigitRaw(1,0); //-
        matrix.writeDigitRaw(3,0); //-
        matrix.writeDigitRaw(4,0); //-
        matrix.writeDisplay();
    }
    else
      {
        Kph = (gps.speed.kmph());
        matrix.print(Kph);
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDisplay();
        Serial.println("Kph ") & Serial.println(gps.speed.kmph()); 
       }
    }
    
    void condition4(){
        if (gps.time.isUpdated())
        Time = ((gps.time.hour()) *100) + gps.time.minute();
        matrix.print(Time);
        matrix.drawColon(true);
        matrix.writeDisplay();
        Serial.println("Time ") & Serial.print((gps.time.hour()) *100)+ gps.time.minute(); 
    }

void setup()
{
  matrix.begin(0x70);
  // matrix.setBrightness(15);
  Serial.begin(115200);
  ss.begin(GPSBaud);
  pinMode(BUTTON_PIN,INPUT_PULLUP);
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5);
}

void loop(){
  while (ss.available() > 0)
    gps.encode(ss.read());
      {
       switch (menu) {
      case 1:
          condition1();
          break;
      case 2:
          condition2();
          break;
      case 3:
          condition3();
          break; 
      case 4:
          condition4();
          break; 
      }
      buttonState();
      }
}
 
If it's working as a prototype, then what do you need help with ?

I've never used an arduino, although I know a couple of people that do. The code shown is pretty simple, but uses many library functions which are device specific and therefore I'm unfamiliar with.
I was under the impression there was a large arduino community with plenty of open source libraries and knowledge available.
 
If it's working as a prototype, then what do you need help with ?

I've never used an arduino, although I know a couple of people that do. The code shown is pretty simple, but uses many library functions which are device specific and therefore I'm unfamiliar with.
I was under the impression there was a large arduino community with plenty of open source libraries and knowledge available.

It is functioning but I can't work out how to add the submenus. If I had an example of one, I'm sure I could adapt it. It is simple enough if you know what you are doing but it's taken me a few weeks to get this far with it. As for storing the selected values in the eeprom, I haven't the foggiest. :D

You can PM me if you would like some help. The changes are pretty straight forward.

Thank you. Will send a PM. :thumb2
 
Current code

Code:
#include <Bounce2.h> //button debouncing
#include <Adafruit_LEDBackpack.h> //required to drive the 7 segment display
#include <Adafruit_GFX.h> //required to drive the 7 segment display
#include <Wire.h> //required to drive the 7 segment display
#include <TinyGPS++.h> //pulls the data from the GPS statements
#include <SoftwareSerial.h> // allows serial communication on digital pins

int Heading;
int Mph;
int Kph;
int Time;

#define BUTTON_1 2
#define BUTTON_2 5

Bounce  debouncer  = Bounce();

Adafruit_7segment matrix = Adafruit_7segment();

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;

SoftwareSerial ss(RXPin, TXPin);

unsigned long last = 0UL;

byte menu = 1;

void buttonState(){
      while (debouncer.update()) {
      if (debouncer.read() == HIGH)
      menu++;
      if (menu>4) menu = 1;
      matrix.clear();
        }
}        
    void condition1()
    {
      if (gps.course.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay(); 
      }
      else
      {
        Heading = (gps.course.deg());
        matrix.print(Heading);
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDisplay();
        Serial.println("Heading ") & Serial.println(gps.course.deg()); 
       }
    }
    
    void condition2()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay();     
      }
    else
      {
        Mph = (gps.speed.mph());
        matrix.print(Mph);
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDisplay();
        Serial.println("Mph ") & Serial.println(gps.speed.mph());  
       }
     }
    
    void condition3()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {      
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDigitRaw(1,0); //-
        matrix.writeDigitRaw(3,0); //-
        matrix.writeDigitRaw(4,0); //-
        matrix.writeDisplay();
    }
    else
      {
        Kph = (gps.speed.kmph());
        matrix.print(Kph);
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDisplay();
        Serial.println("Kph ") & Serial.println(gps.speed.kmph()); 
       }
    }
    
    void condition4(){
        if (gps.time.isUpdated())
        Time = ((gps.time.hour()) *100) + gps.time.minute();
        matrix.print(Time);
        matrix.drawColon(true);
        matrix.writeDisplay();
        Serial.println("Time ") & Serial.print((gps.time.hour()) *100)+ gps.time.minute(); 
    }

void setup()
{
  matrix.begin(0x70);
  // matrix.setBrightness(15);
  Serial.begin(115200);
  ss.begin(GPSBaud);
  pinMode(BUTTON_1,INPUT_PULLUP);
  debouncer.attach(BUTTON_1);
  debouncer.interval(5);
}

void loop(){
  while (ss.available() > 0)
    gps.encode(ss.read());
      {
       switch (menu) {
      case 1:
          condition1();
          break;
      case 2:
          condition2();
          break;
      case 3:
          condition3();
          break; 
      case 4:
          condition4();
          break; 
      }
      buttonState();
      }
}
 
See if this compiles:

Code:
#include  //button debouncing
#include  //required to drive the 7 segment display
#include  //required to drive the 7 segment display
#include  //required to drive the 7 segment display
#include  //pulls the data from the GPS statements
#include  // allows serial communication on digital pins

int Heading;
int Mph;
int Kph;
int Time;

#define BUTTON_1 2
#define BUTTON_2 5

Bounce  debouncer  = Bounce();
Bounce  debouncer2  = Bounce();

Adafruit_7segment matrix = Adafruit_7segment();

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;

SoftwareSerial ss(RXPin, TXPin);

unsigned long last = 0UL;

byte menu = 1;
byte kph = false;
byte bightness = 1;

void buttonState(){
	byte buttonchange = true;
	while (buttonchange)
	{
	     buttonchange = false;
	     if (debouncer.update())
		 {
			if (debouncer.read() == HIGH)
			{
				menu++;
				if (menu>3) menu = 1;
				matrix.clear();
			}
			buttonchange=true;
		}
	     if (debouncer2.update())
		{
			if (debouncer2.read() == HIGH)
			{
				switch (menu)
				{
				case 2:
					kph=!kph;
					matrix.clear();
					break;
				case 3:
					brightness++;
					if (brightness>3) brightness=1;
					matrix.setBrightness(brightness*5);
					matrix.clear();
					break;
				}
			}
			buttonchange=true;
		}
	}
}        
    void conditionHeading()
    {
      if (gps.course.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay(); 
      }
      else
      {
        Heading = (gps.course.deg());
        matrix.print(Heading);
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDisplay();
        Serial.println("Heading ") & Serial.println(gps.course.deg()); 
       }
    }
    
    void conditionMph()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay();     
      }
    else
      {
        Mph = (gps.speed.mph());
        matrix.print(Mph);
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDisplay();
        Serial.println("Mph ") & Serial.println(gps.speed.mph());  
       }
     }
    
    void conditionKph()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {      
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDigitRaw(1,0); //-
        matrix.writeDigitRaw(3,0); //-
        matrix.writeDigitRaw(4,0); //-
        matrix.writeDisplay();
    }
    else
      {
        Kph = (gps.speed.kmph());
        matrix.print(Kph);
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDisplay();
        Serial.println("Kph ") & Serial.println(gps.speed.kmph()); 
       }
    }
    
    void conditionTime(){
        if (gps.time.isUpdated())
        Time = ((gps.time.hour()) *100) + gps.time.minute();
        matrix.print(Time);
        matrix.drawColon(true);
        matrix.writeDisplay();
        Serial.println("Time ") & Serial.print((gps.time.hour()) *100)+ gps.time.minute(); 
    }

void setup()
{
  matrix.begin(0x70);
  // matrix.setBrightness(15);
  Serial.begin(115200);
  ss.begin(GPSBaud);
  pinMode(BUTTON_1,INPUT_PULLUP);
  pinMode(BUTTON_2,INPUT_PULLUP);
  debouncer.attach(BUTTON_1);
  debouncer.interval(5);
  // set up second button debouncer
  debouncer2.attach(BUTTON_2);
  debouncer2.interval(5);
}

void loop(){
  while (ss.available() > 0)
    gps.encode(ss.read());
      {
       switch (menu) {
      case 1:
          conditionHeading();
          break;
      case 2:
			if (kph)
				conditionKph();
			else
				conditionMph();
          break;
      case 3:
          conditionTime();
          break; 
      }
      buttonState();
      }
}
 
This should retain previous settings in eeprom.

Code:
#include <Bounce2.h> //button debouncing
#include <Adafruit_LEDBackpack.h> //required to drive the 7 segment display
#include <Adafruit_GFX.h> //required to drive the 7 segment display
#include <Wire.h> //required to drive the 7 segment display
#include <TinyGPS++.h> //pulls the data from the GPS statements
#include <SoftwareSerial.h> // allows serial communication on digital pins
#include <EEPROM.h>

int Heading;
int Mph;
int Kph;
int Time;

#define BUTTON_1 2
#define BUTTON_2 5

Bounce  debouncer  = Bounce();
Bounce  debouncer2  = Bounce();

Adafruit_7segment matrix = Adafruit_7segment();

static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;

TinyGPSPlus gps;

SoftwareSerial ss(RXPin, TXPin);

unsigned long last = 0UL;

byte menu = 1;
byte kphView = false;
byte brightness = 1;

void buttonState(){
	byte buttonchange = true;
	while (buttonchange)
	{
	     buttonchange = false;
	     if (debouncer.update())
		 {
			if (debouncer.read() == HIGH)
			{
				menu++;
				if (menu>3) menu = 1;
				matrix.clear();
				EEPROM.write(0,menu);
			}
			buttonchange=true;
		}
	     if (debouncer2.update())
		{
			if (debouncer2.read() == HIGH)
			{
				switch (menu)
				{
				case 2:
					kphView=!kphView;
					matrix.clear();
					EEPROM.write(1,kphView);
					break;
				case 3:
					brightness++;
					if (brightness>3) brightness=1;
					matrix.setBrightness(brightness*5);
					matrix.clear();
					EEPROM.write(2,brightness);
					break;
				}
			}
			buttonchange=true;
		}
	}
}        
    void conditionHeading()
    {
      if (gps.course.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay(); 
      }
      else
      {
        Heading = (gps.course.deg());
        matrix.print(Heading);
        matrix.writeDigitRaw(0,118); //H
        matrix.writeDisplay();
        Serial.println("Heading ") & Serial.println(gps.course.deg()); 
       }
    }
    
    void conditionMph()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDigitRaw(1,0); //
        matrix.writeDigitRaw(3,0); //
        matrix.writeDigitRaw(4,0); //
        matrix.writeDisplay();     
      }
    else
      {
        Mph = (gps.speed.mph());
        matrix.print(Mph);
        matrix.writeDigitRaw(0,8); //_
        matrix.writeDisplay();
        Serial.println("Mph ") & Serial.println(gps.speed.mph());  
       }
     }
    
    void conditionKph()
    {
      if (gps.speed.isUpdated())
      if (gps.speed.kmph() <5)
      {      
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDigitRaw(1,0); //-
        matrix.writeDigitRaw(3,0); //-
        matrix.writeDigitRaw(4,0); //-
        matrix.writeDisplay();
    }
    else
      {
        Kph = (gps.speed.kmph());
        matrix.print(Kph);
        matrix.writeDigitRaw(0,1); //~
        matrix.writeDisplay();
        Serial.println("Kph ") & Serial.println(gps.speed.kmph()); 
       }
    }
    
    void conditionTime(){
        if (gps.time.isUpdated())
        Time = ((gps.time.hour()) *100) + gps.time.minute();
        matrix.print(Time);
        matrix.drawColon(true);
        matrix.writeDisplay();
        Serial.println("Time ") & Serial.print((gps.time.hour()) *100)+ gps.time.minute(); 
    }

void setup()
{
  matrix.begin(0x70);
  // matrix.setBrightness(15);
  Serial.begin(115200);
  ss.begin(GPSBaud);
  pinMode(BUTTON_1,INPUT_PULLUP);
  pinMode(BUTTON_2,INPUT_PULLUP);
  debouncer.attach(BUTTON_1);
  debouncer.interval(5);
  // set up second button debouncer
  debouncer2.attach(BUTTON_2);
  debouncer2.interval(5);
  // read previos settings from eeprom
  menu = EEPROM.read(0);
  if (menu<1||menu>3) menu = 1;
  kphView = EEPROM.read(1);
  brightness = EEPROM.read(2);
  if (brightness<1||brightness>3) brightness = 3;
	matrix.setBrightness(brightness*5);
}

void loop(){
  while (ss.available() > 0)
    gps.encode(ss.read());
      {
       switch (menu) {
      case 1:
          conditionHeading();
          break;
      case 2:
			if (kphView)
				conditionKph();
			else
				conditionMph();
          break;
      case 3:
          conditionTime();
          break; 
      }
      buttonState();
      }
}
 
I used to do a bit of 6502 assember, if that's any help ;)

I have absolutely no idea what that is. :D

A big public thank you goes out to GS_or_bust, you're the man. :clap

When the case comes back from the 3D printers it's time to assemble and test.

It's to use on a navigation tower on the bike. They are commercially available but cost £250+ and you also need a GPS and cradle such as a Garmin 60CSX at £100+ (second hand) to feed the CAP repeater the GPS statements.

Total cost for this little project is about £65 and I won't need the separate GPS as I've incorporated it all in the unit.
 


Back
Top Bottom