olikraus / u8glib

Arduino Monochrom Graphics Library for LCDs and OLEDs
https://github.com/olikraus/u8glib/wiki
Other
1.24k stars 313 forks source link

kurze Frage / short Question #509

Open Greenislands opened 4 years ago

Greenislands commented 4 years ago

Grüß dich Oli,

I am a greenhorn in Arduino and programming. Hours of hard testing I then finally got it. A teensy 3.2 board runs the "Hello World" sketch on a Nokia 5110 display. Now to the point. The task is to join two functions: To draw with u8glib to the display data from another library by getting these data with a function.

function of the other library (DcsBios.h) for example is this:

void onIasUsChange(char* newValue) {
    /* your code here */
}
DcsBios::StringBuffer<4> iasUsBuffer(0x0426, onIasUsChange);

Background: Its a flight simulator (DCS World) and the DcsBios.h reads data from the sim and I want to show parts of this data from the sim on the display. The above showed code calls the indicated airspeed from the sim.

So here is the conflict. The u8glib starts drawing by: void draw(void) {

I am not able to integrate the two functions to work with. My first intention dont work:

void onIasUsChange(char* newValue) {
  void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, newValue);
  u8g.drawStr(40, 22, "knots IAS");

}
DcsBios::StringBuffer<4> iasUsBuffer(0x0426, onIasUsChange);

This function calls the value of the indicated airspeed to "newValue" and u8g should print the value at 0, 22. On column 40 starts the text to indicate the value as knots per hour indicated airspeed.

An alternate and the full code also does not work:

#define DCSBIOS_DEFAULT_SERIAL
#include "DcsBios.h"
#include "U8glib.h"

U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8);    // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8

void onIasUsChange(char* newValue) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "newValue");

}
DcsBios::StringBuffer<4> iasUsBuffer(0x0426, onIasUsChange);

void setup(void) {

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
   pinMode(8, OUTPUT);
}

void loop(void) {
    DcsBios::loop();
  // picture loop
  u8g.firstPage();
  do {
    onIasUsChange;
  } while (u8g.nextPage());
}

Can anyone support with his magic? thanks in advance

Maik

olikraus commented 4 years ago

Hallo Maik

There are multiple ways to solve this problem. Here is one suggestion:

  1. Introduce a global buffer: char msg[32];
  2. Fill that buffer in the onIasUsChange function with strncpy
  3. In the main loop, output the value of "msg"
char msg[32];

void onIasUsChange(char* newValue) {
  strncpy(msg, newValue, 32);
 msg[31] = '\0';
}

Then later, do something like this:

void loop(void) {
    DcsBios::loop();
  // picture loop
  u8g.setFont(u8g_font_unifont);
  u8g.firstPage();
  do {
   u8g2.drawStr(0, 22, msg);
  } while (u8g.nextPage());
}

I do not exactly know the ::loop function, but maybe the following might improve reaction time for DcsBios:

void loop(void) {
  DcsBios::loop();
  u8g.setFont(u8g_font_unifont);
  u8g.firstPage();
  do {
    DcsBios::loop();
    u8g2.drawStr(0, 22, msg);
  } while (u8g.nextPage());
}
Greenislands commented 4 years ago

Hey Oli,

it works exactly the way you showed! That kicks my project forward of building an arduino based cockpit.

Big thanks to you for sharing your knowledge! I owe you some beer

Greenislands commented 4 years ago

Okay Oli,

the programming got me another time.

void onAltMslFtChange(unsigned int* newValue) {
  strncpy(ALT, newValue, 32);
  ALT[31] = '\0';
}
DcsBios::IntegerBuffer altMslFtBuffer(0x0432, 0xffff, 0, onAltMslFtChange);

Okay, this time I got another datacall which seems to be an integer output. I am looking if there is any other surprise datatype. no... "unsigned int" is common, "char" is rare. What I have found out is that I cant use strncpy for copying unsigned int types.

How do I get this into the draw loop?

olikraus commented 4 years ago

The msg[32] only was a example. You can use any data.

unsigned int n;
void onAltMslFtChange(unsigned int* newValue) {
  n = newValue;
}

Then later, do something like this:

void loop(void) {
    DcsBios::loop();
  // picture loop
  u8g.setFont(u8g_font_unifont);
  u8g.firstPage();
  do {
    DcsBios::loop();
   u8g2.setCursorPos(0,22);
   u8g2.print(x);
  } while (u8g.nextPage());
}
Greenislands commented 4 years ago

hey ho,

I got it,

setCursorPos

don´t work. After studying the u8g wiki I used setPrintPos instead.

Thank you oli. I swear I read the fucking manual first next time, but I feared of having no basic knowledge of c programming.

olikraus commented 4 years ago

don´t work. After studying the u8g wiki I used setPrintPos instead.

Maybe my mistake. I do not support u8g any more, instead u8g2 is out since several years and I guess I changed the function name here..