454 lines
16 KiB
Arduino
454 lines
16 KiB
Arduino
|
/*********************************************************************
|
||
|
NMM-1
|
||
|
NMEA0183 serial Monitor.
|
||
|
|
||
|
By Jony Silva
|
||
|
Wed 24 Jan 23:11:25 GMT 2018
|
||
|
*********************************************************************/
|
||
|
|
||
|
// Libraries to be included
|
||
|
#include <SPI.h>
|
||
|
#include <Wire.h>
|
||
|
#include <SoftwareSerial.h>
|
||
|
#include <Adafruit_GFX.h>
|
||
|
#include <Adafruit_SSD1306.h>
|
||
|
|
||
|
#define OLED_RESET 8
|
||
|
#define SCREEN_WIDTH 128 // OLED display width, in pixels
|
||
|
#define SCREEN_HEIGHT 56 // OLED display height, in pixels
|
||
|
// create display object for oled display
|
||
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||
|
|
||
|
#define ON 0 // ON means pin is on GND
|
||
|
#define OFF 1 // OFF means pin is on VCC
|
||
|
|
||
|
// Assign switches and led's to arduino pins
|
||
|
#define UP 2 // Switch 1 will be function UP connected to arduino PD 2
|
||
|
#define OK 3 // Switch 2 will be function OK connected to arduino pin 3
|
||
|
#define DOWN 4 // Switch 3 will be function DOWN connected to arduino pin 4
|
||
|
#define CANCEL 5 // Switch 4 will be function CANCEL connected to arduino pin 5
|
||
|
#define led1 9 // Led 1 connected to arduino pin 9
|
||
|
#define led2 10 // Led 2 connected to arduino pin 10
|
||
|
#define batt 17 // Battery plus connected to arduino pin 17
|
||
|
|
||
|
// Macros to read the switchs
|
||
|
#define rUP digitalRead(UP) // Read button UP state
|
||
|
#define rOK digitalRead(OK) // Read button OK state
|
||
|
#define rDOWN digitalRead(DOWN) // Read button DOWN state
|
||
|
#define rCANCEL digitalRead(CANCEL) // Read button CANCEL state
|
||
|
|
||
|
|
||
|
// Function declarations
|
||
|
void one(); // Menu one
|
||
|
void two(); // Menu two
|
||
|
void three(); // Menu three
|
||
|
void four(); // Menu four
|
||
|
void read_serial(); // Menu that reads the serial
|
||
|
void write_gps(); // Menu that writes gps out to serial
|
||
|
void write_hdg(); // Menu that writes hdg out to serial
|
||
|
void write_dep(); // Menu that writes dep out to serial
|
||
|
void batt_icon(); // Draws the battery icon acording to value
|
||
|
void write_serial(); // Menu that writes to serial
|
||
|
|
||
|
|
||
|
|
||
|
// Variables creation
|
||
|
int menuState = 1; // Integer with the number of the menu you are in
|
||
|
int prevMenu = 1; // Previous menu
|
||
|
int UP_state = OFF; // Holds state for UP, either ON or OFF
|
||
|
int OK_state = OFF; // Holds state for OK, either ON or OFF
|
||
|
int DOWN_state = OFF; // Holds state for DOWN, either ON or OFF
|
||
|
int CANCEL_state = OFF; // Holds state for CANCEL, either ON or OFF
|
||
|
int batt_val = 0; // Holds the value of battery voltage
|
||
|
int read_s = 0; // Serial flag, if 0 not reading, if 1 is reading
|
||
|
|
||
|
|
||
|
// Create SoftwareSerial object and designate pins
|
||
|
SoftwareSerial mySerial(6, 7); // RX, TX
|
||
|
|
||
|
void setup() { // BEGIN SETUP ------------------------------------
|
||
|
|
||
|
|
||
|
pinMode(led1, OUTPUT); // Led 1 is an output
|
||
|
pinMode(led2, OUTPUT); // Led 2 is an output
|
||
|
pinMode(UP, INPUT); // Switch 1 is an input
|
||
|
pinMode(OK, INPUT); // Switch 2 is an input
|
||
|
pinMode(DOWN, INPUT); // Switch 3 is an input
|
||
|
pinMode(CANCEL, INPUT); // Switch 4 is an input
|
||
|
|
||
|
// Define the starting state of the led's
|
||
|
digitalWrite(led1,HIGH); // Turn off led 1
|
||
|
digitalWrite(led2,HIGH); // Turn off led 2
|
||
|
|
||
|
// set the data rate for the Serial port
|
||
|
Serial.begin(4800);
|
||
|
|
||
|
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
|
||
|
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
|
||
|
// init done
|
||
|
|
||
|
|
||
|
// initialize timer1 ---------------------------------------
|
||
|
noInterrupts(); // disable all interrupts
|
||
|
TCCR1A = 0;
|
||
|
TCCR1B = 0;
|
||
|
TCNT1 = 0;
|
||
|
|
||
|
OCR1A = 9000; // Load value to compare
|
||
|
TCCR1B |= (1 << WGM12); // CTC mode
|
||
|
TCCR1B |= (1 << CS10); // 64 prescaler
|
||
|
TCCR1B |= (1 << CS11); //
|
||
|
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
|
||
|
interrupts(); // enable all interrupts
|
||
|
// ----------------------------------------------------------
|
||
|
|
||
|
|
||
|
// Clear the buffer.
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.display(); // Refresh display
|
||
|
|
||
|
display.setTextSize(2); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(36,18); // Set the display cursor to position
|
||
|
display.println("NMM-1"); // Print on display
|
||
|
display.display(); // Refresh display
|
||
|
delay(3000);
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.display(); // Refresh display
|
||
|
|
||
|
} // END SETUP --------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
|
||
|
// Timer compare interrupt service routine --------------------------
|
||
|
ISR(TIMER1_COMPA_vect)
|
||
|
{
|
||
|
if (!rUP) // If button UP pressed
|
||
|
{
|
||
|
if (menuState == 1){} // Do nothing and leave menuState
|
||
|
// as it is (1)
|
||
|
else {
|
||
|
menuState--;
|
||
|
}
|
||
|
while (!rUP); // Check if button is still pressed, do nothing
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!rDOWN) // If button DOWN pressed
|
||
|
{
|
||
|
if (menuState == 4){} // Do nothing and leave menuState
|
||
|
// as it is (4)
|
||
|
else {
|
||
|
menuState++;
|
||
|
}
|
||
|
while (!rDOWN); // Check if button is still pressed, do nothing
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!rOK) // If button OK pressed
|
||
|
{
|
||
|
if (menuState == 1) // and the menuState is 1
|
||
|
{
|
||
|
prevMenu = menuState; // set prevMenu to 1
|
||
|
menuState = 10; // then reset menuState to 10
|
||
|
}
|
||
|
else if (menuState == 2) // If menuState is 2
|
||
|
{
|
||
|
prevMenu = menuState; // set prevMenu to 2
|
||
|
menuState = 11; // then reset menuState to 11
|
||
|
}
|
||
|
else if (menuState == 3) // If menuState is 3
|
||
|
{
|
||
|
prevMenu = menuState; // set prevMenu to 3
|
||
|
menuState = 12; // then reset menuState to 12
|
||
|
}
|
||
|
else if (menuState == 4) // If menuState is 4
|
||
|
{
|
||
|
prevMenu = menuState; // set prevMenu to 4
|
||
|
menuState = 13; // then reset menuState to 13
|
||
|
}
|
||
|
while (!rOK); // Check if button is still pressed, do nothing
|
||
|
}
|
||
|
|
||
|
if (!rCANCEL) // If button CANCEL pressed
|
||
|
{
|
||
|
menuState = prevMenu; // set menuState to same value as prevMenu
|
||
|
while (!rCANCEL); // Check if button is still pressed, do nothing
|
||
|
}
|
||
|
|
||
|
}
|
||
|
// End of Timer compare interrupt ---------------------------------------
|
||
|
|
||
|
|
||
|
// Main loop routine -----------------------------------------
|
||
|
void loop()
|
||
|
{
|
||
|
|
||
|
batt_val = analogRead(batt); // Read analog value from battery into batt_val
|
||
|
|
||
|
if (menuState == 1) // If menuState is 1
|
||
|
{
|
||
|
one(); // call function one()
|
||
|
mySerial.end(); // close serial connection
|
||
|
read_s = 0; // and set read_s to 0
|
||
|
}
|
||
|
else if (menuState == 2) // If menuState is 2
|
||
|
{
|
||
|
two(); // call function two()
|
||
|
mySerial.end(); // close serial connection
|
||
|
read_s = 0; // and set read_s to 0
|
||
|
}
|
||
|
else if (menuState == 3) // If menuState is 3
|
||
|
{
|
||
|
three(); // call function three()
|
||
|
mySerial.end(); // close serial connection
|
||
|
read_s = 0; // and set read_s to 0
|
||
|
}
|
||
|
else if (menuState == 4) // If menuState is 4
|
||
|
{
|
||
|
four(); // call function four()
|
||
|
mySerial.end(); // close serial connection
|
||
|
read_s = 0; // and set read_s to 0
|
||
|
}
|
||
|
else if (menuState == 10) // If menuState is 10
|
||
|
{
|
||
|
if (read_s == 0) // and read_s is 0
|
||
|
{
|
||
|
mySerial.begin(4800); // Start serial with 4800bps
|
||
|
read_s = 1; // set read_s to 1
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,17); // Set the display cursor to position
|
||
|
display.println("Sending GPS....."); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
write_gps(); // call function write_gps()
|
||
|
}
|
||
|
else if (menuState == 11) // If menuState is 11
|
||
|
{
|
||
|
if (read_s == 0) // and read_s is 0
|
||
|
{
|
||
|
mySerial.begin(4800); // Start serial with 4800bps
|
||
|
read_s = 1; // set read_s to 1
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,17); // Set the display cursor to position
|
||
|
display.println("Sending Heading....."); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
write_hdg(); // call function write_hdg()
|
||
|
}
|
||
|
else if (menuState == 12) // If menuState is 12
|
||
|
{
|
||
|
if (read_s == 0) // and read_s is 0
|
||
|
{
|
||
|
mySerial.begin(4800); // Start serial with 4800bps
|
||
|
read_s = 1; // set read_s to 1
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,17); // Set the display cursor to position
|
||
|
display.println("Sending Depth....."); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
write_dep(); // call function write_dep()
|
||
|
}
|
||
|
else if (menuState == 13) // If menuState is 13
|
||
|
{
|
||
|
if (read_s == 0) // and read_s is 0
|
||
|
{
|
||
|
mySerial.begin(4800); // Start serial with 4800bps
|
||
|
read_s = 1; // set read_s to 1
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,17); // Set the display cursor to position
|
||
|
display.println("RS-422 to USB"); // Print on display
|
||
|
display.println("Sending..."); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
read_serial(); // call function read_serial()
|
||
|
}
|
||
|
else // otherwise
|
||
|
{
|
||
|
one(); // call function one()
|
||
|
mySerial.end(); // close serial connection
|
||
|
read_s = 0; // set read_s to 0
|
||
|
}
|
||
|
}
|
||
|
// END of Main loop routine -----------------------------------------
|
||
|
|
||
|
|
||
|
|
||
|
void batt_icon (void)
|
||
|
{
|
||
|
|
||
|
|
||
|
if (batt_val > 962) // If analog value is bigger then 962
|
||
|
{
|
||
|
// Draw the battery icon - Full battery
|
||
|
display.drawRect(111, 1, 16, 6, WHITE); // Draw white reactangle with coordinates
|
||
|
display.drawRect(112, 2, 14, 4, WHITE);
|
||
|
display.drawRect(113, 3, 12, 2, WHITE);
|
||
|
display.drawPixel(110, 3, WHITE); // Draw white dot with coordinates
|
||
|
display.drawPixel(110, 4, WHITE);
|
||
|
display.drawPixel(109, 3, WHITE);
|
||
|
display.drawPixel(109, 4, WHITE);
|
||
|
display.drawPixel(108, 3, WHITE);
|
||
|
display.drawPixel(108, 4, WHITE);
|
||
|
}
|
||
|
|
||
|
else if ((batt_val > 901) & (batt_val < 962)) // If analog value is between 901 and 962
|
||
|
{
|
||
|
// Draw the battery icon - 2/3 battery
|
||
|
display.drawRect(111, 1, 16, 6, WHITE); // Draw white reactangle with coordinates
|
||
|
display.drawRect(116, 2, 10, 4, WHITE);
|
||
|
display.drawRect(117, 3, 8, 2, WHITE);
|
||
|
display.drawPixel(110, 3, WHITE); // Draw white dot with coordinates
|
||
|
display.drawPixel(110, 4, WHITE);
|
||
|
display.drawPixel(109, 3, WHITE);
|
||
|
display.drawPixel(109, 4, WHITE);
|
||
|
display.drawPixel(108, 3, WHITE);
|
||
|
display.drawPixel(108, 4, WHITE);
|
||
|
}
|
||
|
|
||
|
else if ((batt_val > 840) & (batt_val < 901)) // If analog value is between 840 and 901
|
||
|
{
|
||
|
// Draw the battery icon - 1/3 battery
|
||
|
display.drawRect(111, 1, 16, 6, WHITE); // Draw white reactangle with coordinates
|
||
|
display.drawRect(121, 2, 5, 4, WHITE);
|
||
|
display.drawRect(122, 3, 3, 2, WHITE);
|
||
|
display.drawPixel(110, 3, WHITE); // Draw white dot with coordinates
|
||
|
display.drawPixel(110, 4, WHITE);
|
||
|
display.drawPixel(109, 3, WHITE);
|
||
|
display.drawPixel(109, 4, WHITE);
|
||
|
display.drawPixel(108, 3, WHITE);
|
||
|
display.drawPixel(108, 4, WHITE);
|
||
|
}
|
||
|
|
||
|
else // otherwise
|
||
|
{
|
||
|
// Draw the battery icon - Empty battery
|
||
|
display.setCursor(35,1); // Set the display cursor to position
|
||
|
display.println("BATT LOW"); // Print on display
|
||
|
display.drawRect(111, 1, 16, 6, WHITE); // Draw white reactangle with coordinates
|
||
|
display.drawPixel(110, 3, WHITE); // Draw white dot with coordinates
|
||
|
display.drawPixel(110, 4, WHITE);
|
||
|
display.drawPixel(109, 3, WHITE);
|
||
|
display.drawPixel(109, 4, WHITE);
|
||
|
display.drawPixel(108, 3, WHITE);
|
||
|
display.drawPixel(108, 4, WHITE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void one (void)
|
||
|
{
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,18); // Set the display cursor to position
|
||
|
display.println("Send GPS <--"); // Print on display
|
||
|
display.setCursor(1,28); // Set the display cursor to position
|
||
|
display.println("Send Heading"); // Print on display
|
||
|
display.setCursor(1,38); // Set the display cursor to position
|
||
|
display.println("Send Depth"); // Print on display
|
||
|
display.setCursor(1,48); // Set the display cursor to position
|
||
|
display.println("RS422 <==> USB"); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
|
||
|
void two (void)
|
||
|
{
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,18); // Set the display cursor to position
|
||
|
display.println("Send GPS"); // Print on display
|
||
|
display.setCursor(1,28); // Set the display cursor to position
|
||
|
display.println("Send Heading <--"); // Print on display
|
||
|
display.setCursor(1,38); // Set the display cursor to position
|
||
|
display.println("Send Depth"); // Print on display
|
||
|
display.setCursor(1,48); // Set the display cursor to position
|
||
|
display.println("RS422 <==> USB"); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
|
||
|
void three (void)
|
||
|
{
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,18); // Set the display cursor to position
|
||
|
display.println("Send GPS"); // Print on display
|
||
|
display.setCursor(1,28); // Set the display cursor to position
|
||
|
display.println("Send Heading"); // Print on display
|
||
|
display.setCursor(1,38); // Set the display cursor to position
|
||
|
display.println("Send Depth <--"); // Print on display
|
||
|
display.setCursor(1,48); // Set the display cursor to position
|
||
|
display.println("RS422 <==> USB"); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
|
||
|
void four (void)
|
||
|
{
|
||
|
display.clearDisplay(); // Clean display
|
||
|
display.setTextSize(1); // Set text size on the display
|
||
|
display.setTextColor(WHITE); // Set text color on the display
|
||
|
display.setCursor(1,18); // Set the display cursor to position
|
||
|
display.println("Send GPS"); // Print on display
|
||
|
display.setCursor(1,28); // Set the display cursor to position
|
||
|
display.println("Send Heading"); // Print on display
|
||
|
display.setCursor(1,38); // Set the display cursor to position
|
||
|
display.println("Send Depth"); // Print on display
|
||
|
display.setCursor(1,48); // Set the display cursor to position
|
||
|
display.println("RS422 <==> USB <--"); // Print on display
|
||
|
batt_icon(); // call function batt_icon()
|
||
|
display.display(); // Refresh display
|
||
|
}
|
||
|
|
||
|
void read_serial (void)
|
||
|
{
|
||
|
if (mySerial.available()) // If incoming NMEA0183 serial
|
||
|
{
|
||
|
Serial.write(mySerial.read()); // redirect it to USB
|
||
|
}
|
||
|
|
||
|
if (Serial.available()) // If incoming USB serial
|
||
|
{
|
||
|
mySerial.write(Serial.read()); // redirect it to NMEA0183 serial
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void write_gps (void)
|
||
|
{
|
||
|
// Write NMEA0183 GPS sentence to USB
|
||
|
mySerial.print("$GPGGA,090000.10,6350.37829338,N,02225.18272240,W,1,05,2.87,160.00,M,-21.3213,M,,*64");
|
||
|
mySerial.println(); // Send string to NMEA0183 serial
|
||
|
delay(100);
|
||
|
}
|
||
|
|
||
|
void write_hdg (void)
|
||
|
{
|
||
|
// Write NMEA0183 Heading sentence to USB
|
||
|
mySerial.print("$HEHDT,268.4,T*27");
|
||
|
mySerial.println(); // Send string to NMEA0183 serial
|
||
|
delay(100);
|
||
|
}
|
||
|
|
||
|
void write_dep (void)
|
||
|
{
|
||
|
// Write NMEA0183 Depth sentence to USB
|
||
|
mySerial.print("$SDDBT,0038.0,f,0011.6,M,0006.3,F");
|
||
|
mySerial.println(); // Send string to NMEA0183 serial
|
||
|
delay(100);
|
||
|
}
|