Sunday, 2 February 2020

Nano Pi neo OLED HAT C++

Nano Pi neo OLED HAT without the python OLED

Post by marius » Tue Sep 10, 2019 4:37 pm
Recently I purchased a nano hat oled for nano pi neo. It had the python oled application.
I hacked that to display what I would like. The board stopped working after a day or 2.
I thought that my GPSD program leaks or something. Then I realized that the crappy python and friends
was hanging up the board. I did not catch it, because the board was not running. I eliminated
the python oled services and everything went back to normal.

The sdcard is available at the https://www.redypis.org/?pd=17

DIY.
  • Remove the python NanoHatOLED service if you already have it running.

  • Configure the buttons at startup
Code: Select all
#!/bin/bash
pushd /sys/class/gpio
echo 0 > export
echo 2 > export
echo 3 > export
echo in  > ./gpio0/direction
echo in  > ./gpio2/direction
echo in  > ./gpio3/direction
popd

  • Get the libSSD1306
  • Patch the code
  • The ./examples/tempprint.cxx new file content would print the output of /tmp/oled file every second. The file is listed at the bottom.
    Create a new file in ./examples/tempprint.cxx and paste that content.
Code: Select all
marius@odrisyan1:~$ cd libSSD1306/
marius@odrisyan1:~/libSSD1306$ 
  • The patch file
Code: Select all
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 930b7fe..8fea5cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,6 +8,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
 
+add_definitions(-Dcimg_display=0 -Dcimg_use_jpeg)
+
 #--------------------------------------------------------------------------
 
 add_library(SSD1306 STATIC lib/FileDescriptor.cxx
@@ -34,6 +36,9 @@ target_link_libraries(clock SSD1306)
 add_executable(ipaddress examples/ipaddress.cxx examples/LinuxKeys.cxx)
 target_link_libraries(ipaddress SSD1306)
 
+add_executable(tempprint examples/tempprint.cxx examples/LinuxKeys.cxx)
+target_link_libraries(tempprint SSD1306)
+
 add_executable(life examples/life.cxx examples/LinuxKeys.cxx)
 target_link_libraries(life SSD1306)
 
diff --git a/examples/analog.cxx b/examples/analog.cxx
index e1fed84..f7ceb93 100644
--- a/examples/analog.cxx
+++ b/examples/analog.cxx
@@ -158,7 +158,7 @@ main()
 
         SSD1306::OledBitmap<64, 64> bitmap;
         SSD1306::OledPoint offset{32, 0};
-        SSD1306::OledI2C oled{"/dev/i2c-1", 0x3C};
+        SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};
 
         while (run)
         {
diff --git a/examples/clock.cxx b/examples/clock.cxx
index 94a5d08..914d24d 100644
--- a/examples/clock.cxx
+++ b/examples/clock.cxx
@@ -133,7 +133,7 @@ main()
             }
         }
 
-        SSD1306::OledI2C oled{"/dev/i2c-1", 0x3C};
+        SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};
 
         while (run)
         {
diff --git a/examples/ipaddress.cxx b/examples/ipaddress.cxx
index 2af0e30..2502787 100644
--- a/examples/ipaddress.cxx
+++ b/examples/ipaddress.cxx
@@ -155,7 +155,7 @@ main()
             }
         }
 
-        SSD1306::OledI2C oled{"/dev/i2c-1", 0x3C};
+        SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};
 
         while (run)
         {
diff --git a/examples/life.cxx b/examples/life.cxx
index ca742c7..2da44b4 100644
--- a/examples/life.cxx
+++ b/examples/life.cxx
@@ -220,7 +220,7 @@ main()
             }
         }
 
-       SSD1306::OledI2C oled{"/dev/i2c-1", 0x3C};
+       SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};
 
         Bitmap pixels;
 
diff --git a/examples/testbitmap.cxx b/examples/testbitmap.cxx
index ba2d334..44a499a 100644
--- a/examples/testbitmap.cxx
+++ b/examples/testbitmap.cxx
@@ -61,7 +61,7 @@ main()
              0b00000000, 0b00000000
         };
 
-        SSD1306::OledI2C oled{"/dev/i2c-1", 0x3C};
+        SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};
 
         for (auto y = -(bitmap.height() / 2) ;
              y < (oled.height() + (bitmap.height() / 2)) ;
diff --git a/examples/testoled.cxx b/examples/testoled.cxx
index cba0723..4e45ea4 100644
--- a/examples/testoled.cxx
+++ b/examples/testoled.cxx
@@ -39,7 +39,7 @@ main()
 {
     try
     {
-        SSD1306::OledI2C oled{"/dev/i2c-1", 0x3C};
+        SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};
         drawString8x16(SSD1306::OledPoint{32, 24},
                        "Oled I" "\xFD" "C",
                        SSD1306::PixelStyle::Set,
  • cmake and make
Code: Select all
marius@odrisyan1:~/libSSD1306$ make -j4
-- Configuring done
-- Generating done
-- Build files have been written to: /home/marius/libSSD1306
[ 30%] Built target SSD1306
[ 40%] Building CXX object CMakeFiles/testbitmap.dir/examples/testbitmap.cxx.o
[ 40%] Building CXX object CMakeFiles/life.dir/examples/life.cxx.o
[ 40%] Building CXX object CMakeFiles/testoled.dir/examples/testoled.cxx.o
[ 43%] Building CXX object CMakeFiles/tempprint.dir/examples/tempprint.cxx.o
[ 46%] Building CXX object CMakeFiles/testoled.dir/examples/LinuxKeys.cxx.o
[ 50%] Building CXX object CMakeFiles/testbitmap.dir/examples/LinuxKeys.cxx.o
[ 53%] Linking CXX executable bin/testoled
[ 56%] Linking CXX executable bin/testbitmap
[ 56%] Built target testoled
[ 56%] Built target testbitmap
[ 60%] Building CXX object CMakeFiles/tempprint.dir/examples/LinuxKeys.cxx.o
[ 63%] Building CXX object CMakeFiles/analog.dir/examples/analog.cxx.o
[ 66%] Building CXX object CMakeFiles/life.dir/examples/LinuxKeys.cxx.o
[ 70%] Building CXX object CMakeFiles/analog.dir/examples/LinuxKeys.cxx.o
[ 73%] Linking CXX executable bin/life
[ 76%] Building CXX object CMakeFiles/clock.dir/examples/clock.cxx.o
[ 76%] Built target life
[ 80%] Building CXX object CMakeFiles/ipaddress.dir/examples/ipaddress.cxx.o
[ 86%] Linking CXX executable bin/analog
[ 86%] Building CXX object CMakeFiles/clock.dir/examples/LinuxKeys.cxx.o
[ 90%] Linking CXX executable bin/clock
[ 90%] Built target analog
[ 93%] Building CXX object CMakeFiles/ipaddress.dir/examples/LinuxKeys.cxx.o
[ 93%] Built target clock
[ 96%] Linking CXX executable bin/ipaddress
[ 96%] Built target ipaddress
[100%] Linking CXX executable bin/tempprint
[100%] Built target tempprint
You can run samples now
Code: Select all
cd bin
marius@odrisyan1:~/libSSD1306/bin$ ls -l
total 352
-rwxrwxr-x 1 marius marius 50204 Feb 11 11:58 analog
-rwxrwxr-x 1 marius marius 49192 Feb 11 11:58 clock
-rwxrwxr-x 1 marius marius 48876 Feb 11 11:58 ipaddress
-rwxrwxr-x 1 marius marius 44460 Feb 11 11:57 life
-rwxrwxr-x 1 marius marius 65496 Feb 11 11:58 tempprint
-rwxrwxr-x 1 marius marius 44876 Feb 11 11:57 testbitmap
-rwxrwxr-x 1 marius marius 48708 Feb 11 11:57 testoled
marius@odrisyan1:~/libSSD1306/bin$ 

Image
Image
Image
Image


  • tempprint.cxx file
Code: Select all
#include <array>
#include <chrono>
#include <cmath>
#include <csignal>
#include <cstring>
#include <string>
#include <exception>
#include <iostream>
#include <sstream>
#include <fstream>
#include <memory>
#include <thread>
#include <system_error>
#include <vector>

#include <sys/types.h>
#include <time.h>
#include <unistd.h>


#include "OledFont8x16.h"
#include "OledFont8x12.h"
#include "OledFont8x8.h"
#include "OledBitmap.h"
#include "OledGraphics.h"

#include "OledI2C.h"
#include "cimg.h"


using namespace cimg_library;
//-------------------------------------------------------------------------

namespace 
{
 volatile static std::sig_atomic_t run = 1;
}


//-------------------------------------------------------------------------

static void
signalHandler(
    int signalNumber)
{
    switch (signalNumber)
    {
    case SIGINT:
    case SIGTERM:

        run = 0;
        break;
    };
}

int split(const std::string& s, const char* delim, std::vector<std::string>& a)
{
    const char* pdelim=delim;
    std::string st;
    std::istringstream ss(s);
    a.clear();
    while(*pdelim)
    {
        if(s.find(*pdelim)!=std::string::npos)
        {
            while (getline(ss, st, *pdelim))
            {
                a.push_back(st);
            }
            return a.size();
        }
        ++pdelim;
    }
    return 0;
}

//-------------------------------------------------------------------------
//CImg
void scanTemp( SSD1306::OledI2C& oled)
{
 static std::string prev;
 std::string current;
 std::vector<std::string> lines;
 std::ifstream s;
 std::string ss;

 s.open( "/tmp/oled", std::ios::in);
 if(s.is_open())
 {
  while(!s.eof())
  {
      std::getline(s,ss);
      current.append(ss);
      lines.push_back(ss);
      ss.clear();
  }
  s.close();
 }

 if(prev != current)
 {
  std::vector<std::string> tokens;
  prev = current;
  oled.clear();
  for(const auto& l : lines)
  {
   //1,2,3,l,c,string
   split(l, ",", tokens);
   if(tokens.size()==5 && tokens[0]=="T") // T|1|4|4|text
   {
    int font = ::atoi(tokens[1].c_str());
    int line = ::atoi(tokens[3].c_str());
    int row  = ::atoi(tokens[2].c_str());

    if(font<=1)
     drawString8x8(SSD1306::OledPoint{line, row},
                              tokens[4].c_str(),
                              SSD1306::PixelStyle::Set,
                              oled);
    else if(font==2)
     drawString8x12(SSD1306::OledPoint{line, row},
                              tokens[4].c_str(),
                              SSD1306::PixelStyle::Set,
                              oled);
    else if(font==3)
     drawString8x16(SSD1306::OledPoint{line, row},
                              tokens[4].c_str(),
                              SSD1306::PixelStyle::Set,
                              oled);
   }
   else if(tokens.size() == 6 && tokens[0]=="I") //I,X,Y,W,H,file.png
   {
/*
    int line = ::atoi(tokens[1].c_str());
    int row  = ::atoi(tokens[2].c_str());
    int w = ::atoi(tokens[3].c_str());
    int h  = ::atoi(tokens[4].c_str());
           CImg<unsigned char> image(tokens[5].c_str()),
                 gray(image.width(), image.height(), 1, 1, 0),
                grayWeight(image.width(), image.height(), 1, 1, 0),
                imgR(image.width(), image.height(), 1, 3, 0),
                imgG(image.width(), image.height(), 1, 3, 0),
                imgB(image.width(), image.height(), 1, 3, 0);
    
    cimg_forXY(image,x,y)
    {
     std::cout << x << y << "\n";
            int R = (int)image(x,y,0,0);
         int G = (int)image(x,y,0,1);
         int B = (int)image(x,y,0,2);
     int grayValueWeight = (int)(0.299*R + 0.587*G + 0.114*B);
    }
*/
   }
  }
  oled.displayUpdate();
 }
}

//-------------------------------------------------------------------------

int main()
{
    try
    {
        constexpr std::array<int, 2> signals{SIGINT, SIGTERM};

        for (auto signal : signals)
        {
            if (std::signal(signal, signalHandler) == SIG_ERR)
            {
                std::string what{"installing "};
                what += strsignal(signal);
                what += " signal handler";

                throw std::system_error(errno,
                                        std::system_category(),
                                        what);
            }
        }

        SSD1306::OledI2C oled{"/dev/i2c-0", 0x3C};

        while (run)
        {
            scanTemp(oled);
            ::usleep(128000);
        }

        oled.clear();
        oled.displayUpdate();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << "\n";
    }

    return 0;
}

No comments:

Post a Comment