Issue with A-10C altimeter display using DCS-BIOS - ED Forums
 


Notices

Reply
 
Thread Tools Display Modes
Old 01-14-2016, 02:25 AM   #1
Adrian_gc
Junior Member
 
Join Date: Jun 2015
Posts: 36
Default Issue with A-10C altimeter display using DCS-BIOS

Hi, I need help with the representation of height in an OLED display.
I have write a code on arduino uno using DCS-BIOS to represent the height in an OLED display. When I run the program and the airplane is on the ground, the display shows up perfectly, if I turn the Rotary altimeter also perfectly synchronized shows. The problem happens when the plane is in flight. It is seen on the screen height is represented with a mix of numbers, usually the "3" ... "333" as if it were an interference. After leaving the plane on autopilot stable, the screen displays the most stable height, still, occasionally remixed numbers.

Here I attached a copy of the code I'm using, also 2 videos of what happens on the ground and in flight.

Anyone would think that might be happening? thank you.

Videos:

[ame]https://www.youtube.com/watch?v=3Q2jVzB1wVY[/ame]
[ame]https://www.youtube.com/watch?v=7St3D2UtKNI[/ame]

Code:
#include <DcsBios.h>
#include <Servo.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_MOSI 9
#define OLED_CLK 10
#define OLED_DC 11
#define OLED_CS 12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


char primer='-';
char segundo='-';
char tercero='-';
char cuarto='0';
char quinto='0';
char writing=0;
int val=0;




/**** In most cases, you do not have to change anything below this line ****/

/* Instantiate a ProtocolParser object to parse the DCS-BIOS export stream */
DcsBios:rotocolParser parser;

void setup() {
Serial.begin(500000);


display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.clearDisplay();
}



/*
Your main loop needs to pass data from the DCS-BIOS export
stream to the parser object you instantiated above.

It also needs to call DcsBios:ollingInput::pollInputs()
to detect changes in the state of connected controls and
pass them on to DCS.
*/
void loop() {
char pepe[6];
// feed incoming data to the parser
while (Serial.available()) {
parser.processChar(Serial.read());
}

// poll inputs
DcsBios:ollingInput::pollInputs();

sprintf(pepe, "%c%c%cA%c", primer, segundo, tercero, cuarto, quinto);

writing=1;

display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(30,5);
display.write(primer);
display.write(segundo);
display.write(tercero);
display.write(cuarto);
display.write(quinto);
//display.println();
display.display();

delay (75);
writing=0;

}

/*
You need to define
void sendDcsBiosMessage(const char* msg, const char* arg)
so that the string msg, followed by a space, the string arg
and a newline gets sent to the DCS-BIOS import stream.

In this example we send it to the serial port, so you need to
run socat to read the data from the serial port and send it
over UDP to DCS-BIOS.

If you are using an Ethernet Shield, you would probably want
to send a UDP packet from this subroutine.
*/
void sendDcsBiosMessage(const char* msg, const char* arg) {
Serial.write(msg);
Serial.write(' ');
Serial.write(arg);
Serial.write('\n');
}

char mapeo(unsigned int valor){


if (valor < 6553) { return '0'; }
if (valor < 13107) { return '1'; }
if (valor < 19660) { return '2'; }
if (valor < 26214) { return '3'; }
if (valor < 32767) { return '4'; }
if (valor < 39321) { return '5'; }
if (valor < 45874) { return '6'; }
if (valor < 5242 { return '7'; }
if (valor < 58981) { return '8'; }
return '9' ;


}

/*
This subroutine gets called every time a message is received
from the export stream (you need to define it even if it
does nothing).

Use this to handle outputs which are not covered by the
DcsBios Arduino library (e.g. displays).
*/
void onDcsBiosWrite(unsigned int address, unsigned int value) {


if (!writing){
if (address == 0x1080) {
primer=mapeo(value);
}
else if (address == 0x1082) {
segundo=mapeo(value);
}
else if (address == 0x1084) {
tercero=mapeo(value);
}



}
}
Adrian_gc is offline   Reply With Quote
Old 01-14-2016, 08:44 AM   #2
BravoYankee4
Member
 
BravoYankee4's Avatar
 
Join Date: Sep 2015
Location: Sweden
Posts: 611
Default

You need to change the video security settings, since they are now "private" and can't be viewed.
BravoYankee4 is offline   Reply With Quote
Old 01-14-2016, 12:07 PM   #3
[FSF]Ian
ED Testers Team
 
Join Date: Feb 2013
Location: Germany
Posts: 1,290
Default

Hint: use [code] tags for source code, makes it a lot easier to read by using a monospace font and also disables smileys.

Can't view the video, but I assume what happens here is that in flight, the receive buffer fills up while you are writing to the display, which leads to incoming data being dropped on the floor, confusing the protocol parser, and ending up with garbage on the display.

It does not happen on the ground because the receive buffer is large enough to handle the smaller amount of data that is being sent (in the air, a lot more values are changing all the time).

Try using the Arduino Library in the new rs485 branch on GitHub. See this post for more information. You can download that as a .zip archive here:
https://github.com/dcs-bios/dcs-bios...hive/rs485.zip

You will have to change the baud rate in connect-serial-port.cmd to 250000, that's the new standard.

The new interrupt-based communication handling is designed to solve this exact problem (only works on ATMega328-based controllers at the moment).

I'll try to edit a code example into this post later.
EDIT: with the new library, you could try this code:
Code:
// tell DCS-BIOS we want interrupt-based serial comms. How to do this will probably change in the future.
#define DCSBIOS_IRQ_SERIAL

#include <DcsBios.h>
#include <Servo.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

char* displayString = "---00";

// onDcsBiosWrite does not exist anymore, use Int16Buffers instead
DcsBios::Int16Buffer alt10000ftCounter(0x1080);
DcsBios::Int16Buffer alt1000ftCounter(0x1082);
DcsBios::Int16Buffer alt100ftCounter(0x1084);

void setup() {
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
  display.clearDisplay();
  
  DcsBios::setup();
}


void loop() {
  DcsBios::loop();
  
  if (alt10000ftCounter.hasUpdatedData()) { displayString[0] = mapeo(alt10000ftCounter.getData()); }
  if (alt1000ftCounter.hasUpdatedData()) { displayString[1] = mapeo(alt1000ftCounter.getData()); }
  if (alt100ftCounter.hasUpdatedData()) { displayString[2] = mapeo(alt100ftCounter.getData()); }
  
  display.clearDisplay();
  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(30,5);
  display.print(displayString);
  display.display();

  delay (75);

}

char mapeo(unsigned int valor){


  if (valor < 6553) { return '0'; }
  if (valor < 13107) { return '1'; }
  if (valor < 19660) { return '2'; }
  if (valor < 26214) { return '3'; }
  if (valor < 32767) { return '4'; }
  if (valor < 39321) { return '5'; }
  if (valor < 45874) { return '6'; }
  if (valor < 52428) { return '7'; }
  if (valor < 58981) { return '8'; }
  return '9' ;
  

}

Last edited by [FSF]Ian; 01-14-2016 at 12:47 PM.
[FSF]Ian is offline   Reply With Quote
Old 01-14-2016, 12:12 PM   #4
Gadroc
Senior Member
 
Join Date: Aug 2009
Location: Ohio, USA
Posts: 1,056
Default

You're problem is the baud rate. 500k baud is to fast for the Arduino to keep up with.

Change Serial.bevin(500000h) to Serial.begin(250000) and make a similar change in the software you're using to relay dcsbios to the serial port.
Gadroc is offline   Reply With Quote
Old 01-14-2016, 12:16 PM   #5
Gadroc
Senior Member
 
Join Date: Aug 2009
Location: Ohio, USA
Posts: 1,056
Default

Also you should only update the display on a frame end, unless you move to the newer library Ian posted.
Gadroc is offline   Reply With Quote
Old 01-14-2020, 01:50 PM   #6
lesthegrngo
Member
 
Join Date: Jul 2018
Location: Budapest
Posts: 254
Default

Guys, is there an equivalent sketch available for I2C OLEDS?

Cheers

Les
lesthegrngo is offline   Reply With Quote
Old 01-14-2020, 02:24 PM   #7
Matchstick
Member
 
Join Date: Oct 2007
Posts: 140
Default

Quote:
Originally Posted by lesthegrngo View Post
Guys, is there an equivalent sketch available for I2C OLEDS?

Cheers

Les
The Adafruit_SSD1306 supports I2C displays a well so if youre display works with that you could use the same code, just change the display definitions and constructor.

eg replace

#define OLED_MOSI 9
#define OLED_CLK 10
#define OLED_DC 11
#define OLED_CS 12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

with something like

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

To find out what your display needs I'd try the I2C demos for the SSD1306 library and see what works for you.
Matchstick is offline   Reply With Quote
Old 01-15-2020, 11:33 AM   #8
lesthegrngo
Member
 
Join Date: Jul 2018
Location: Budapest
Posts: 254
Default

Thanks, will have a bash at that

Cheers

Les
lesthegrngo is offline   Reply With Quote
Old 01-18-2020, 11:48 AM   #9
lesthegrngo
Member
 
Join Date: Jul 2018
Location: Budapest
Posts: 254
Default

Hi guys, me yet again

As usual my issue is getting the sketches to work when the hardware is slightly different. I'm using a buysdisplay 0.96" 128 x 64 display, but I also want to use a 0.87" OLED module.

Trying to use the code above this is what I got to that works OK

Code:
// tell DCS-BIOS we want interrupt-based serial comms. How to do this will probably change in the future.
#define DCSBIOS_IRQ_SERIAL

#include <DcsBios.h>

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

char* displayString = "---";

// onDcsBiosWrite does not exist anymore, use Int16Buffers instead
DcsBios::Int16Buffer alt10000ftCounter(0x1080);
DcsBios::Int16Buffer alt1000ftCounter(0x1082);
DcsBios::Int16Buffer alt100ftCounter(0x1084);

void setup() {
  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
  display.clearDisplay();
  
  DcsBios::setup();
}


void loop() {
  DcsBios::loop();
  
  if (alt10000ftCounter.hasUpdatedData()) { displayString[0] = mapeo(alt10000ftCounter.getData()); }
  if (alt1000ftCounter.hasUpdatedData()) { displayString[1] = mapeo(alt1000ftCounter.getData()); }
  if (alt100ftCounter.hasUpdatedData()) { displayString[2] = mapeo(alt100ftCounter.getData()); }
  
  display.clearDisplay();
  display.setTextSize(6);
  display.setTextColor(WHITE);
  display.setCursor(5,0);
  display.print(displayString);
  display.display();

  delay (75);

}

char mapeo(unsigned int valor){


  if (valor < 6553) { return '0'; }
  if (valor < 13107) { return '1'; }
  if (valor < 19660) { return '2'; }
  if (valor < 26214) { return '3'; }
  if (valor < 32767) { return '4'; }
  if (valor < 39321) { return '5'; }
  if (valor < 45874) { return '6'; }
  if (valor < 52428) { return '7'; }
  if (valor < 58981) { return '8'; }
  return '9' ;
  

}
This works on the 0.96" module, with a max text size of 6, anything bigger and it clips. However the numerals displayed are very crude and blockish, presumably due to the bitmap character library being equally crude, so I would like to know if there is a better library I can use for this.

It also strangely will not load on a Nano board, with an error message that it is too big coming up. I have it on an Uno board, on which it works fine. Is there something that I can do to reduce it so that it fits on the Nano? **EDIT** tried on another Nano board and it compiled fine - no idea why

Lastly I tried with the 0.87" module, and there things get a bit weird. I can get it to display by reducing the character size, but it displays the characters back to front, by which I mean it looks like you are looking at them in a mirror. As I want to modify the sketch for use with the Fuel Quantity indication and the pressure indication, I need this to display correctly, so does anyone have any ideas what is causing it?

This video here shows what I would ultimately like to do

https://www.youtube.com/watch?v=gp8maRS7XB0

The scrolling of the digits is a great touch, and I downloaded the sketch and the bespoke libraries, and tried to reverse engineer what he had done with what I managed to get working above, this sketch being the result. I worked through a load of the error messages by installing some libraries within the Adafruit one

Code:
/*
Based on the Adafruit_SSD1306 library demo and the DCS-BIOS template sketch.

This is meant to be compiled with Energia and to run on a
Texas Instruments Tiva C Series Launchpad board.

It should run on an Arduino (adjust the #defines accordingly
to specify the pins you used), but I have not tested whether
the 16 MHz AVR is fast enough.
The Tiva C Launchpad has an 80 MHz ARM processor.

The fonts are not perfectly aligned because they were made
in a hurry to get a proof of concept...

*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DcsBios.h>
#include <Servo.h>

#include "digits_32x64.cpp"
#include "digits_00_32x64.cpp"
#include "digits_1to9_32x64.cpp"

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// If using software SPI (the default case):
//#define OLED_MOSI  PE_1
//#define OLED_CLK   PE_2
//#define OLED_DC    PD_3
//#define OLED_CS    PB_7
//#define OLED_RESET PD_2
//Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

DcsBios::ProtocolParser parser;

void drawDigit(unsigned int index, unsigned int offset, unsigned char* bits) {
  //double y_offset = (double)offset / 65535.0d;
  //unsigned int y_offset_lines = y_offset * 640;
  unsigned int y_offset_lines = offset / 103;
   display.fillRect(32*index, 0, 32, 64, BLACK);
   display.drawXBitmap(32*index, 0, &bits[4*y_offset_lines], 32, 64, WHITE);
   display.display();   
}

void setup()   {                
  //Serial.begin(500000);
  
  display.begin(SSD1306_SWITCHCAPVCC);

  display.clearDisplay();
  drawDigit(0, 0, digits_1to9_32x64_bits);
  drawDigit(1, 0, digits_32x64_bits);
  drawDigit(2, 0, digits_32x64_bits);
  drawDigit(3, 0, digits_00_32x64_bits);
}


void loop() {
  while(Serial.available()) parser.processChar(Serial.read());
}

void onDcsBiosWrite(unsigned int address, unsigned int value) {
  address = address & 0xffff;
  value = value & 0xffff;
  if (address == 0x1080) {
    unsigned int alt10000ftCntValue = (value & 0xffff) >> 0;
    drawDigit(0, alt10000ftCntValue, digits_1to9_32x64_bits);
  }
  
  if (address == 0x1082) {
    unsigned int alt1000ftCntValue = (value & 0xffff) >> 0;
    drawDigit(1, alt1000ftCntValue, digits_32x64_bits);
  }
  
  if (address == 0x1084) {
    unsigned int alt100ftCntValue = (value & 0xffff) >> 0;
    drawDigit(2, alt100ftCntValue, digits_32x64_bits);
  }
}
Unfortunately it just gives errors at the end, saying it's unable to compile for either of the arduinos, which is a shame as it would have been great to have a working version

Cheers

Les

Last edited by lesthegrngo; 01-18-2020 at 02:40 PM.
lesthegrngo is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT. The time now is 09:39 AM. vBulletin Skin by ForumMonkeys. Powered by vBulletin®.
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.