MapleCoOS and U8g2lib

Working libraries, libraries being ported and related hardware
idahowalker
Posts: 26
Joined: Fri Nov 09, 2018 1:13 pm

MapleCoOS and U8g2lib

Post by idahowalker » Fri Nov 16, 2018 5:34 pm

Code: Select all

#include 
#include 
#include 
#include 
#include 
// #include "uTimerLib.h" // this works
#include  //for function sprintf
//
//
// xSemaphoreHandle xDisplayFree;
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//////
#define GPSTimerInterval 1 //mSec
#define BuiltInLED PC13
#define AnalogInPA0 PA0
#define LED_BlinkInterval 1000
#define DEGREE 600000
#define DistaceResetPin PB0
#define StartStopDistanceCounterPin PB1
#define Priority2 2
#define Priority3 3
#define Priority4 4
#define Priority5 5
// #define FiveHundred 500
// #define EightHundred 800
#define OneK 1000
#define TwoK 2000
#define ThreeK 3000
// #define TenK 10000
/////////////////////////////////
// OS_MutexID xGPS_Parse;
OS_STK vBlinkBuiltIn[TASK_STK_SIZE];
OS_STK vGPSSIGNAL[TASK_STK_SIZE];
OS_STK vGPS_Parse[TASK_STK_SIZE];
OS_STK vDoVoltage_PA0[TASK_STK_SIZE];
OS_STK vDoScreen[TASK_STK_SIZE + 500];
//???????????????????????????????????????????
//Name of the hardware serial port
#define GPSSerial Serial1
// Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial);
// UltimateGPS rx to STM32 PA2 - Serial1
// UltimateGPS tx to STM32 PA3 - Serial1
//?????????????????????????????????????????
volatile int iTicCount = 0; //counts milliseconds
bool bLED_On = false;
long lGPS_Lat0 = 0;
long lGPS_Lon0 = 0;
float floatDistance = 0.0;
float floatVbatt = 0.0;
float BattPercent = 0;
//***************************************************************************************
//// Interrupt is called once a millisecond, does a data read so main loop can parse GPS data
//***************************************************************************************
static void GPSSIGNAL ( void *pdata )
{
  for (;;)
  {
    // CoTickDelay( GPSTimerInterval );
    //cause a GPS data read so that the if (GPS.newNMEAreceived()) can do its thing.
    GPS.read();
  }
} // static void GPSSIGNAL ( void *pdata )
static void fDoVoltage_PA0 ( void *pdata )
{
  float r1 = 47000.0;                       // R1 in ohm, 47k = 47000.0
  float r2 = 10000.0;                       // R2 in ohm, 10k = 10000.0
  float r_divider = r2 / (r1 + r2);
  for (;;)
  {
    // CoTickDelay( 10000 );
    // Serial.print ( "fDoVoltage_PA0 ");
    // Serial.println(  analogRead( AnalogInPA0 ) );
    float adcin = analogRead( AnalogInPA0 );            // read ADC from PA0 or other PAx pin
    //    if ( adcin != 0.0 )
    //    {
    float voltage = 3.3 / 4095 * adcin;       // voltage at the PA0, ref voltage is 3.3V and 12bit ADC is 4095 steps
    floatVbatt = voltage / r_divider;      // calculate the voltage at the divider's input
    fBatteryPercentRemaingCharge();
    //    }
  }
} //  static void fDoVoltage_PA0 ( void *pdata )
void fBatteryPercentRemaingCharge()
{
  byte V_BattNominal = 8;
  byte V_MinRange = 6; //volts is lowest recomemded operating voltage
  ////
  if (floatVbatt >= V_BattNominal)
  {
    BattPercent = 100.00;
    return;
  }
  else if (V_MinRange > floatVbatt)
  {
    BattPercent = 0.00;
    return;
  }
  else
  {
    BattPercent = ((floatVbatt - V_MinRange) * 100.0) / (V_BattNominal - V_MinRange);
  }
}// end fBatteryPercentRemaingCharge()
static void fBlinkBuiltIn( void *pdata )
{
  for (;;)
  {
    // Sleep for 1000 milliseconds.
    digitalWrite(BuiltInLED, HIGH);
    CoTickDelay( LED_BlinkInterval );
    // vTaskDelay( LED_BlinkInterval );
    // vTaskDelay( (1000L * configTICK_RATE_HZ) / 1000L );
    digitalWrite(BuiltInLED, LOW);
    CoTickDelay( LED_BlinkInterval );
    // vTaskDelay( (1000L * configTICK_RATE_HZ) / 1000L );
    // vTaskDelay( LED_BlinkInterval );
  }
} // static void fBlinkBuiltIn( void *pdata )
// https://github.com/olikraus/u8g2/wiki/fntlistall << font list
static void fGPS_Parse( void *pdata )
{
  for (;;)
  {
    // CoTickDelay( TwoK );
    //leave this code alone!!!!!!!!!!!!!!!!!!!!!
    //query GPS: has a new complete chunk of data been received?
    // Serial.println( "fGPS_Parse" );
    if (GPS.newNMEAreceived())
    {
      // Serial.println( "GPS.newNMEAreceived()" );
      //    //if received cause parse data
      if (GPS.parse(GPS.lastNMEA()))
        // if data is parsed do the thing if there is a fix
        if ( GPS.fix )
        {
          // CoEnterMutexSection ( xGPS_Parse );
          fCalDistance();
          // CoLeaveMutexSection( xGPS_Parse );
        }
    }
  }
} // static void fGPS_Parse( void *pdata )
//*****************************************************************************************
//
//*****************************************************************************************
static void fDoScreen( void *pdata )
{
  static int iCount = 0;
  float f = 0.0;
  static char buf[20];
  //
  for (;;)
  {
    // CoTickDelay( OneK );
    //Serial.println( "fDoScreen0" );
    // Serial.flush();
    u8g2.clearBuffer(); // clear the internal memory
    // Serial.println( "fDoScreen1" );
    // Serial.flush();
    // 
    u8g2.setFont(u8g2_font_t0_11_te);  //
    sprintf(buf, "UTC %02d:%02d:%02d", GPS.hour, GPS.minute, GPS.seconds);
    u8g2.setCursor(0, 10); u8g2.print(buf);
    u8g2.drawStr(88, 10, "^");
    u8g2.setCursor(96, 10); u8g2.print(GPS.satellites);
    //
      sprintf(buf, "Date: %02d/%02d/%02d", GPS.day, GPS.month, GPS.year);
      u8g2.setCursor(0, 23); u8g2.print(buf);
    //
      f = (GPS.latitude / 100);
      u8g2.setCursor(20, 37) ; u8g2.print(int(f));
      f = GPS.latitude - (int(f) * 100);
      u8g2.setCursor(40, 37); u8g2.print(f);
      u8g2.setCursor(83, 37); u8g2.print(GPS.lat);
      //
      f = (GPS.longitude / 100);
      u8g2.setCursor(20, 47); u8g2.print(int(f));
      f = GPS.longitude - (int(f) * 100);
      u8g2.setCursor(40, 47); u8g2.print(f);
      u8g2.drawCircle(45, 47, 1,  U8G2_DRAW_ALL);
      u8g2.setCursor(83, 47); u8g2.print(GPS.lon);
      //
      if ( (iCount >= 0) &&  (iCount <= 4) )
      {
        u8g2.drawStr(0, 60, "Hdg:");
        u8g2.setCursor(28, 60); u8g2.print(GPS.angle);
      }
      if ( (iCount >= 5) &&  (iCount <= 9) )
      {
        u8g2.drawStr(0, 60, "Alti:");
        u8g2.setCursor(30, 60); u8g2.print((GPS.altitude * 3.2808));
      }
      if ( (iCount >= 10) &&  (iCount <= 14) )
      {
        u8g2.drawStr(0, 60, "Dist:");
        u8g2.setCursor(40, 60); u8g2.print( floatDistance );
      }
      if ( (iCount >= 15) &&  (iCount <= 19) )
      {
        sprintf( buf, "V: %02d", floatVbatt );
        u8g2.setCursor(0, 60); u8g2.print( buf );
      }
      u8g2.sendBuffer(); // transfer internal memory to the display
      iCount++;
      if ( iCount >= 20 )
      {
        iCount = 0;
      }
  }
} // void fDoScreen()
//*****************************************************************************************
//
//*****************************************************************************************
void fCalDistance()
{
  // if (digitalRead(StartStopDistanceCounterPin) == 0)
  // {
  // if previous is zero then seed
  if ( lGPS_Lat0 == 0 )
  {
    lGPS_Lat0 = fDegreeToDecimal( GPS.latitudeDegrees );
    lGPS_Lon0  = fDegreeToDecimal( GPS.longitudeDegrees );
  }
  long tempLat = fDegreeToDecimal( GPS.latitudeDegrees );
  long tempLon = fDegreeToDecimal( GPS.longitudeDegrees );
  //
  //add new distance to previous distance, meters to mile* 0.00062137
  floatDistance = floatDistance + ( DistanceBetween(lGPS_Lat0, lGPS_Lon0, tempLat, tempLon) * 0.00062137 );
  //reset to last used measuring point
  lGPS_Lat0 = tempLat;
  lGPS_Lon0 = tempLon;
  // }
}// end void fCalDistance()
unsigned int CosFix (long angle)
{
  long u = labs(angle) >> 16;
  u = (u * u * 6086) >> 24;
  return 246 - u;
} // unsigned int CosFix (long angle)
long Diff (long deg1, long deg2)
{
  long result = deg2 - deg1;
  if (result > 180 * DEGREE) return result - 360 * DEGREE;
  else if (result < -180 * DEGREE) return result + 360 * DEGREE;
  else return result;
} // long Diff (long deg1, long deg2)
//calculates distance between 2 points . using lat/lon. ignores earth curve, valid for distances of several 100K, returns meters
//www.technoblogy.com/show?LNQ
unsigned int DistanceBetween (long lat1, long long1, long lat2, long long2)
{
  long dx = (Diff(long2, long1) * CosFix((lat1 + lat2) / 2)) / 256;
  long dy = Diff(lat2, lat1);
  unsigned long adx = labs(dx);
  unsigned long ady = labs(dy);
  unsigned long b = max(adx, ady);
  unsigned long a = min(adx, ady);
  if (b == 0) return 0;
  return 95 * (b + (110 * a / b * a + 128) / 256) / 512;
} // unsigned int DistanceBetween (long lat1, long long1, long lat2, long long2)
long fDegreeToDecimal(long floatDegree)
{
  return floatDegree  * 60 * 10000;
} // long fDegreeToDecimal(long floatDegree)
//This returns 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, or 7=NW.
int Cardinal (unsigned int dir) {
  return (((dir * 2 + 45) / 90) & 7);
}
//*****************************************************************************************
//
//*****************************************************************************************
// the setup function runs once when you press reset or power the board
void setup()
{
  Serial.begin(115200);
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // has speed n altitude
  // Note you must send both commands below to change both the output rate (how often the position is written to the serial line), and the position fix rate. 1 Hz update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PMTK_API_SET_FIX_CTL_1HZ);
  //turn off antenna data being sent
  GPS.sendCommand("$PGCMD,33,0*6D/r/n");
  //speed threshold level
  //0/0.2/0.4/0.5/0.8/1.0/1.5/2.0 m/s
  //GPS.sendCommand("$PMTK397,0.2*3F/r/n");
  delay(1000);
  // Ask for firmware version
  // GPSSerial.println(PMTK_Q_RELEASE);
  // initialize digital pin BuiltInLED as an output.
  pinMode(BuiltInLED, OUTPUT);
  // set pinmode analog pin
  pinMode( AnalogInPA0, INPUT_ANALOG );
  //
  u8g2.begin();
  // TimerLib.setInterval_s( fDoScreen, 4 ); // callback, seconds to wait before running call back
  //
  CoInitOS();
  //  xGPS_Parse = CoCreateMutex();
  CoCreateTask( GPSSIGNAL, (void *)0 , Priority5, &vGPSSIGNAL[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fBlinkBuiltIn, (void *)0 , Priority2, &vBlinkBuiltIn[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fGPS_Parse, (void *)0 , Priority4, &vGPS_Parse[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fDoVoltage_PA0, (void *)0 , Priority2, &vDoVoltage_PA0[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fDoScreen, (void *)0 , Priority4, &vDoScreen[TASK_STK_SIZE -1], TASK_STK_SIZE );
  ////
  CoStartOS();
} // void setup(}
////////////////////////////
void loop() {} //void loop()
////////////////////////////
That's my code.

I am trying to get the MapleCoOS or any of the other xxxRTOS thingy and the U8g2lib to work together. I settled on the MapleCoOS as it seems to work the best. The MapleCoOS will even, from time to time, work with the U8g2lib if I use uTimerLib.h to run the U8g2lib. The issue I have with uTimerLib.h is that it is a memory hog.

I am using built by Chine STM32F103C8T6 ARM board. I am programming in the Arduino IDE.

The problem is upon a u8g2.begin(); the CoCreateTask's stop working; all of them

Thanks for taking the time to read this posting and if you have any suggestions, I am all ears.

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: MapleCoOS and U8g2lib

Post by mrburnette » Fri Nov 16, 2018 11:57 pm

idahowalker wrote:
Fri Nov 16, 2018 5:34 pm
...
I am using built by Chine STM32F103C8T6 ARM board. I am programming in the Arduino IDE.

The problem is upon a u8g2.begin(); the CoCreateTask's stop working; all of them

Thanks for taking the time to read this posting and if you have any suggestions, I am all ears.
Ummmm,

I noticed in reviewing your introductory post that you are also using ESP32. As you know, the Arduino core for the ESP32 is using FreeRTOS to manage threads across both of the microcontroller cpu. I found this example from MIT which indicates that ESP32, Arduino core, and u8g2 do work properly together. https://iesc-s2.mit.edu/608/spring18/do ... ion/SH1106

Obviously, this does nothing to help with the STM32 board, but sometimes digging into these graphic libraries and pseudo-threads is just too much of a headache. Just my 2 cents. I have a couple of ESP32 projects here.

Ray

idahowalker
Posts: 26
Joined: Fri Nov 09, 2018 1:13 pm

Re: MapleCoOS and U8g2lib

Post by idahowalker » Sat Nov 17, 2018 6:03 pm

Oi! When I read your reply, last night, I had just finished converting the code to use an ESP32 with freeRTOS. Works great. Now I have a STM32 waiting for a project.

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: MapleCoOS and U8g2lib

Post by mrburnette » Sat Nov 17, 2018 10:04 pm

idahowalker wrote:
Sat Nov 17, 2018 6:03 pm
Oi! When I read your reply, last night, I had just finished converting the code to use an ESP32 with freeRTOS. Works great. Now I have a STM32 waiting for a project.
:!:

The STM32F1XX is a great little uC. I'm sure you'll find something to do with it.... I have a few off-the-wall projects on my projects page.

The latest published project uses a Maple Mini to front-end a Raspberry Pi Internet radio.


Ray

User avatar
Bear in There
Posts: 31
Joined: Tue Nov 20, 2018 9:30 pm

Re: MapleCoOS and U8g2lib

Post by Bear in There » Sat Dec 22, 2018 6:16 pm

I've' using u8g2 with U8G2_SH1106_128X64_NONAME_F_HW_I2C quite successfully on my current Project (no RTOS)

I did find that if I wasn't careful, even simple sampling in the main loop could be seriously affected.

u8g2 is a great library but it works on a buffer system, you never have direct access to a pixel without transferring a whole screen (not quite true, I believe that you can break the screen buffer up into parts and only update what you need).

But the point being if you keep transfering 1Kb of data every time you display function is call it's going to create a big system hit.

I have 2 sugestions.
1. track your data and if it hasn't changed don't update the display.
2. Use a timer to trigerr you display function and set the frame rate at a number your system can handle.

Both should stop wasted I2C data transfers and free up resources.
Good artists copy; great artists steal. (Incorrectly accredited to Pablo Picaso by Steve Jobs)

idahowalker
Posts: 26
Joined: Fri Nov 09, 2018 1:13 pm

Re: MapleCoOS and U8g2lib

Post by idahowalker » Sun Dec 23, 2018 4:16 pm

Bear in There wrote:
Sat Dec 22, 2018 6:16 pm
I have 2 sugestions.
1. track your data and if it hasn't changed don't update the display.
2. Use a timer to trigerr you display function and set the frame rate at a number your system can handle.
I have moved the project to an ESP32 where it is working well. My latest change was to add a 128X128 OLED display module. I am currently testing the code and changes with the 128X128 module.

What I think happened was, after i added in the code to convert Lat/Lon to UTM, a floating point intense operation, I pushed physical limitations.

It is my plan to use the STM32's for Application Specific Tasks. As an example, I am using a STM32 connected to a MPU unit, calibrate the MPU, to read the MPU data, convert the MPU data to servo microsecond torque values, and to send those values to a RPi for further processing and application.

Thank you, very much, for your suggestions. I will keep your suggestions in mind for later projects; I've wrote them down in my project notebook.

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: MapleCoOS and U8g2lib

Post by mrburnette » Sun Dec 23, 2018 9:33 pm

idahowalker wrote:
Sun Dec 23, 2018 4:16 pm
...
I have moved the project to an ESP32 where it is working well. My latest change was to add a 128X128 OLED display module. I am currently testing the code and changes with the 128X128 module.
...
Great :D

Remember, your ESP32 is dual-core and uses FreeRTOS... so, you can cycle-steal from cpu0 if the RF section is not overly tasked.
https://www.hackster.io/rayburne/esp32- ... both-cores

Ray

idahowalker
Posts: 26
Joined: Fri Nov 09, 2018 1:13 pm

Re: MapleCoOS and U8g2lib

Post by idahowalker » Sun Dec 23, 2018 10:49 pm

I'm hoping those dual core STM32's start showing up in my shopping arena.

User avatar
Naguissa
Posts: 86
Joined: Sun May 03, 2015 10:38 am
Location: Barcelona, Spain
Contact:

Re: MapleCoOS and U8g2lib

Post by Naguissa » Fri Dec 28, 2018 11:43 pm

idahowalker wrote:
Fri Nov 16, 2018 5:34 pm

Code: Select all

#include 
#include 
#include 
#include 
#include 
// #include "uTimerLib.h" // this works
#include  //for function sprintf
//
//
// xSemaphoreHandle xDisplayFree;
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//////
#define GPSTimerInterval 1 //mSec
#define BuiltInLED PC13
#define AnalogInPA0 PA0
#define LED_BlinkInterval 1000
#define DEGREE 600000
#define DistaceResetPin PB0
#define StartStopDistanceCounterPin PB1
#define Priority2 2
#define Priority3 3
#define Priority4 4
#define Priority5 5
// #define FiveHundred 500
// #define EightHundred 800
#define OneK 1000
#define TwoK 2000
#define ThreeK 3000
// #define TenK 10000
/////////////////////////////////
// OS_MutexID xGPS_Parse;
OS_STK vBlinkBuiltIn[TASK_STK_SIZE];
OS_STK vGPSSIGNAL[TASK_STK_SIZE];
OS_STK vGPS_Parse[TASK_STK_SIZE];
OS_STK vDoVoltage_PA0[TASK_STK_SIZE];
OS_STK vDoScreen[TASK_STK_SIZE + 500];
//???????????????????????????????????????????
//Name of the hardware serial port
#define GPSSerial Serial1
// Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial);
// UltimateGPS rx to STM32 PA2 - Serial1
// UltimateGPS tx to STM32 PA3 - Serial1
//?????????????????????????????????????????
volatile int iTicCount = 0; //counts milliseconds
bool bLED_On = false;
long lGPS_Lat0 = 0;
long lGPS_Lon0 = 0;
float floatDistance = 0.0;
float floatVbatt = 0.0;
float BattPercent = 0;
//***************************************************************************************
//// Interrupt is called once a millisecond, does a data read so main loop can parse GPS data
//***************************************************************************************
static void GPSSIGNAL ( void *pdata )
{
  for (;;)
  {
    // CoTickDelay( GPSTimerInterval );
    //cause a GPS data read so that the if (GPS.newNMEAreceived()) can do its thing.
    GPS.read();
  }
} // static void GPSSIGNAL ( void *pdata )
static void fDoVoltage_PA0 ( void *pdata )
{
  float r1 = 47000.0;                       // R1 in ohm, 47k = 47000.0
  float r2 = 10000.0;                       // R2 in ohm, 10k = 10000.0
  float r_divider = r2 / (r1 + r2);
  for (;;)
  {
    // CoTickDelay( 10000 );
    // Serial.print ( "fDoVoltage_PA0 ");
    // Serial.println(  analogRead( AnalogInPA0 ) );
    float adcin = analogRead( AnalogInPA0 );            // read ADC from PA0 or other PAx pin
    //    if ( adcin != 0.0 )
    //    {
    float voltage = 3.3 / 4095 * adcin;       // voltage at the PA0, ref voltage is 3.3V and 12bit ADC is 4095 steps
    floatVbatt = voltage / r_divider;      // calculate the voltage at the divider's input
    fBatteryPercentRemaingCharge();
    //    }
  }
} //  static void fDoVoltage_PA0 ( void *pdata )
void fBatteryPercentRemaingCharge()
{
  byte V_BattNominal = 8;
  byte V_MinRange = 6; //volts is lowest recomemded operating voltage
  ////
  if (floatVbatt >= V_BattNominal)
  {
    BattPercent = 100.00;
    return;
  }
  else if (V_MinRange > floatVbatt)
  {
    BattPercent = 0.00;
    return;
  }
  else
  {
    BattPercent = ((floatVbatt - V_MinRange) * 100.0) / (V_BattNominal - V_MinRange);
  }
}// end fBatteryPercentRemaingCharge()
static void fBlinkBuiltIn( void *pdata )
{
  for (;;)
  {
    // Sleep for 1000 milliseconds.
    digitalWrite(BuiltInLED, HIGH);
    CoTickDelay( LED_BlinkInterval );
    // vTaskDelay( LED_BlinkInterval );
    // vTaskDelay( (1000L * configTICK_RATE_HZ) / 1000L );
    digitalWrite(BuiltInLED, LOW);
    CoTickDelay( LED_BlinkInterval );
    // vTaskDelay( (1000L * configTICK_RATE_HZ) / 1000L );
    // vTaskDelay( LED_BlinkInterval );
  }
} // static void fBlinkBuiltIn( void *pdata )
// https://github.com/olikraus/u8g2/wiki/fntlistall << font list
static void fGPS_Parse( void *pdata )
{
  for (;;)
  {
    // CoTickDelay( TwoK );
    //leave this code alone!!!!!!!!!!!!!!!!!!!!!
    //query GPS: has a new complete chunk of data been received?
    // Serial.println( "fGPS_Parse" );
    if (GPS.newNMEAreceived())
    {
      // Serial.println( "GPS.newNMEAreceived()" );
      //    //if received cause parse data
      if (GPS.parse(GPS.lastNMEA()))
        // if data is parsed do the thing if there is a fix
        if ( GPS.fix )
        {
          // CoEnterMutexSection ( xGPS_Parse );
          fCalDistance();
          // CoLeaveMutexSection( xGPS_Parse );
        }
    }
  }
} // static void fGPS_Parse( void *pdata )
//*****************************************************************************************
//
//*****************************************************************************************
static void fDoScreen( void *pdata )
{
  static int iCount = 0;
  float f = 0.0;
  static char buf[20];
  //
  for (;;)
  {
    // CoTickDelay( OneK );
    //Serial.println( "fDoScreen0" );
    // Serial.flush();
    u8g2.clearBuffer(); // clear the internal memory
    // Serial.println( "fDoScreen1" );
    // Serial.flush();
    // 
    u8g2.setFont(u8g2_font_t0_11_te);  //
    sprintf(buf, "UTC %02d:%02d:%02d", GPS.hour, GPS.minute, GPS.seconds);
    u8g2.setCursor(0, 10); u8g2.print(buf);
    u8g2.drawStr(88, 10, "^");
    u8g2.setCursor(96, 10); u8g2.print(GPS.satellites);
    //
      sprintf(buf, "Date: %02d/%02d/%02d", GPS.day, GPS.month, GPS.year);
      u8g2.setCursor(0, 23); u8g2.print(buf);
    //
      f = (GPS.latitude / 100);
      u8g2.setCursor(20, 37) ; u8g2.print(int(f));
      f = GPS.latitude - (int(f) * 100);
      u8g2.setCursor(40, 37); u8g2.print(f);
      u8g2.setCursor(83, 37); u8g2.print(GPS.lat);
      //
      f = (GPS.longitude / 100);
      u8g2.setCursor(20, 47); u8g2.print(int(f));
      f = GPS.longitude - (int(f) * 100);
      u8g2.setCursor(40, 47); u8g2.print(f);
      u8g2.drawCircle(45, 47, 1,  U8G2_DRAW_ALL);
      u8g2.setCursor(83, 47); u8g2.print(GPS.lon);
      //
      if ( (iCount >= 0) &&  (iCount <= 4) )
      {
        u8g2.drawStr(0, 60, "Hdg:");
        u8g2.setCursor(28, 60); u8g2.print(GPS.angle);
      }
      if ( (iCount >= 5) &&  (iCount <= 9) )
      {
        u8g2.drawStr(0, 60, "Alti:");
        u8g2.setCursor(30, 60); u8g2.print((GPS.altitude * 3.2808));
      }
      if ( (iCount >= 10) &&  (iCount <= 14) )
      {
        u8g2.drawStr(0, 60, "Dist:");
        u8g2.setCursor(40, 60); u8g2.print( floatDistance );
      }
      if ( (iCount >= 15) &&  (iCount <= 19) )
      {
        sprintf( buf, "V: %02d", floatVbatt );
        u8g2.setCursor(0, 60); u8g2.print( buf );
      }
      u8g2.sendBuffer(); // transfer internal memory to the display
      iCount++;
      if ( iCount >= 20 )
      {
        iCount = 0;
      }
  }
} // void fDoScreen()
//*****************************************************************************************
//
//*****************************************************************************************
void fCalDistance()
{
  // if (digitalRead(StartStopDistanceCounterPin) == 0)
  // {
  // if previous is zero then seed
  if ( lGPS_Lat0 == 0 )
  {
    lGPS_Lat0 = fDegreeToDecimal( GPS.latitudeDegrees );
    lGPS_Lon0  = fDegreeToDecimal( GPS.longitudeDegrees );
  }
  long tempLat = fDegreeToDecimal( GPS.latitudeDegrees );
  long tempLon = fDegreeToDecimal( GPS.longitudeDegrees );
  //
  //add new distance to previous distance, meters to mile* 0.00062137
  floatDistance = floatDistance + ( DistanceBetween(lGPS_Lat0, lGPS_Lon0, tempLat, tempLon) * 0.00062137 );
  //reset to last used measuring point
  lGPS_Lat0 = tempLat;
  lGPS_Lon0 = tempLon;
  // }
}// end void fCalDistance()
unsigned int CosFix (long angle)
{
  long u = labs(angle) >> 16;
  u = (u * u * 6086) >> 24;
  return 246 - u;
} // unsigned int CosFix (long angle)
long Diff (long deg1, long deg2)
{
  long result = deg2 - deg1;
  if (result > 180 * DEGREE) return result - 360 * DEGREE;
  else if (result < -180 * DEGREE) return result + 360 * DEGREE;
  else return result;
} // long Diff (long deg1, long deg2)
//calculates distance between 2 points . using lat/lon. ignores earth curve, valid for distances of several 100K, returns meters
//www.technoblogy.com/show?LNQ
unsigned int DistanceBetween (long lat1, long long1, long lat2, long long2)
{
  long dx = (Diff(long2, long1) * CosFix((lat1 + lat2) / 2)) / 256;
  long dy = Diff(lat2, lat1);
  unsigned long adx = labs(dx);
  unsigned long ady = labs(dy);
  unsigned long b = max(adx, ady);
  unsigned long a = min(adx, ady);
  if (b == 0) return 0;
  return 95 * (b + (110 * a / b * a + 128) / 256) / 512;
} // unsigned int DistanceBetween (long lat1, long long1, long lat2, long long2)
long fDegreeToDecimal(long floatDegree)
{
  return floatDegree  * 60 * 10000;
} // long fDegreeToDecimal(long floatDegree)
//This returns 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, or 7=NW.
int Cardinal (unsigned int dir) {
  return (((dir * 2 + 45) / 90) & 7);
}
//*****************************************************************************************
//
//*****************************************************************************************
// the setup function runs once when you press reset or power the board
void setup()
{
  Serial.begin(115200);
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // has speed n altitude
  // Note you must send both commands below to change both the output rate (how often the position is written to the serial line), and the position fix rate. 1 Hz update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
  GPS.sendCommand(PMTK_API_SET_FIX_CTL_1HZ);
  //turn off antenna data being sent
  GPS.sendCommand("$PGCMD,33,0*6D/r/n");
  //speed threshold level
  //0/0.2/0.4/0.5/0.8/1.0/1.5/2.0 m/s
  //GPS.sendCommand("$PMTK397,0.2*3F/r/n");
  delay(1000);
  // Ask for firmware version
  // GPSSerial.println(PMTK_Q_RELEASE);
  // initialize digital pin BuiltInLED as an output.
  pinMode(BuiltInLED, OUTPUT);
  // set pinmode analog pin
  pinMode( AnalogInPA0, INPUT_ANALOG );
  //
  u8g2.begin();
  // TimerLib.setInterval_s( fDoScreen, 4 ); // callback, seconds to wait before running call back
  //
  CoInitOS();
  //  xGPS_Parse = CoCreateMutex();
  CoCreateTask( GPSSIGNAL, (void *)0 , Priority5, &vGPSSIGNAL[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fBlinkBuiltIn, (void *)0 , Priority2, &vBlinkBuiltIn[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fGPS_Parse, (void *)0 , Priority4, &vGPS_Parse[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fDoVoltage_PA0, (void *)0 , Priority2, &vDoVoltage_PA0[TASK_STK_SIZE - 1], TASK_STK_SIZE );
  CoCreateTask( fDoScreen, (void *)0 , Priority4, &vDoScreen[TASK_STK_SIZE -1], TASK_STK_SIZE );
  ////
  CoStartOS();
} // void setup(}
////////////////////////////
void loop() {} //void loop()
////////////////////////////
That's my code.

I am trying to get the MapleCoOS or any of the other xxxRTOS thingy and the U8g2lib to work together. I settled on the MapleCoOS as it seems to work the best. The MapleCoOS will even, from time to time, work with the U8g2lib if I use uTimerLib.h to run the U8g2lib. The issue I have with uTimerLib.h is that it is a memory hog.

I am using built by Chine STM32F103C8T6 ARM board. I am programming in the Arduino IDE.

The problem is upon a u8g2.begin(); the CoCreateTask's stop working; all of them

Thanks for taking the time to read this posting and if you have any suggestions, I am all ears.

You could post an issue on uTimerLib's GitHub to ask about this... ;)

I'll investigate the memory hog issue on stm32...

User avatar
Naguissa
Posts: 86
Joined: Sun May 03, 2015 10:38 am
Location: Barcelona, Spain
Contact:

Re: MapleCoOS and U8g2lib

Post by Naguissa » Sun Dec 30, 2018 3:33 pm

Simple test done:




uTimerLib_setInterval_us_led library example

uTimerLib enabled (untouched sketch):

El Sketch usa 13692 bytes (12%) del espacio de almacenamiento de programa. El máximo es 110592 bytes.
Las variables Globales usan 2872 bytes (16%) de la memoria dinámica, dejando 14536 bytes para las variables locales. El máximo es 17408 bytes.



Sketch: 13692 bytes
Variables: 2872 bytes



uTimerLib disabled (include commented, TimerLib usage commented and timed_function called on loop):

El Sketch usa 12924 bytes (11%) del espacio de almacenamiento de programa. El máximo es 110592 bytes.
Las variables Globales usan 2824 bytes (16%) de la memoria dinámica, dejando 14584 bytes para las variables locales. El máximo es 17408 bytes.



Sketch 12924 bytes
Variables: 2824 bytes





Maybe the function was discarded by compiler when not using uTimerLib, because it was not called. Who nows, but numbers doesn't seem to be such different to call it a memory hog....

Post Reply