Menu

Using GCB with Generic MAX7219 Module and Arduino Nano

Awais
2018-11-27
2019-01-04
1 2 > >> (Page 1 of 2)
  • Awais

    Awais - 2018-11-27

    I am trying to use Generic MAX7219 8x8 Dot Matrix module with GCB and Arduino Nano 328P. After using the example file, the following are the observations.

    1. Display is 90 degree rotated with reference to IC.
    2. The message starts on the farthest module from Arduino Nano.

    YouTube video link is here https://youtu.be/9t5RB3dxJD4
    Any solution to this issue or any guidance how to change the library files to adopt this module?

    Thanks and regards,
    Awais

     

    Last edit: Awais 2018-11-27
  • Anobium

    Anobium - 2018-11-27

    Hello

    When I wrote the library, I guessed but did not know, that these Matrixes would be upside down.

    Add this to your user program. This should rotate the matrix.

    #define Pset max7219_LEDMatrix_PSet_90

    Once we have the matrix the correct way around we can adapt for write direction.

     
  • Awais

    Awais - 2018-11-27

    Thank you. Now, text is scrolling correctly. But in my hardware design the text should be upside down. So, the command should be something similar to

    define Pset max7219_LEDMatrix_PSet_270

    and the first module connected to Nano is the first from right hand side. So, text scrolling should be from right to left.

    YouTube video link is here https://youtu.be/A6L7K7WLLnU

     

    Last edit: Awais 2018-11-27
    • Anobium

      Anobium - 2018-11-27

      I am being dim? but, just rotate the matrix... or, am I missing something?

       
      • Awais

        Awais - 2018-11-28

        You are right. That is one solution but there are other concerns due to which I cannot rotate it.

         
  • Anobium

    Anobium - 2018-11-27

    As a test, as I have NOT tested. Do exactly the following:

    Add the is code unchanged to your program.

    If this works then I can explain later.

      #define Max7219_LEDMatrix_ScrollMessage Max7219_LEDMatrix_ScrollMessageOut
    
    
      Sub Max7219_LEDMatrix_ScrollMessageOut( in OutMessage as string, In max7219_MessageTime As Word )
    
        dim max7219_ScrollLen, max7219_ScrollPosition, max7219_XScrollPosition as word
        max7219_ScrollLen = OutMessage(0) * GLCDFontWidth
    
        max7219_XScrollPosition = 0'Max7219_PixelBytes-1
    
        For max7219_ScrollPosition = 0 to max7219_ScrollLen-1
          Max7219_LEDMatrix_ClearBuffer ( Max7219_Image_Buffer() ,Max7219_PixelBytes)
          GLCDPrint(max7219_XScrollPosition, 0,  OutMessage)
          max7219_XScrollPosition++
          Max7219_LEDMatrix_SendBuffer ( Max7219_Image_Buffer() ,Max7219_PixelBytes)
          if max7219_MessageTime > 0 then
              Wait max7219_MessageTime ms
          end if
        Next
    
      End Sub
    
     

    Last edit: Anobium 2018-11-27
  • Anobium

    Anobium - 2018-11-27

    I have posted a revised method. This shows the basic left to right scroll. My first attempt failed. :-(

    The original library was based on a right to left scroll that is used on the UK train system. :-)

    To understand. Think of the matrix as a set of pixel, they are stored in memory. The pixels are updated using the GLCD command set. Then, the methods set the memory to the display.

    You should be able to change the library to do a lot more than I have in the library.

    Anobium

     
    • Awais

      Awais - 2018-11-28

      Yes, the message should scroll from right to left but I am surprised that why it is from left to right in my hardware (right one is the first module which is connected to Arduino). I tested Parola library for Arduino and its ok but there are issues of consistency. But with GCB its good. The system is running fine. Now, the orientation and scrolling direction have to be controlled. I will try to understand the routines to tune it for the requirements.

      Please update here if you come up with the solution.

      Thanks and regards,
      Awais

       
      • Anobium

        Anobium - 2018-11-28

        I would look at PSET. The PSET updates the internal memory array, the other routines then send the memory array to the matrixes.

        The matrixes are so differernt. I have learnt this recently. Some are left to right, up and down and other dont work.

        So, look at PSET - this updates memory array then adapt the routines that update the devices... with respect to direction. Sounds so easy.

         
  • Awais

    Awais - 2018-12-06

    Demo video using GCB, Arduino Nano, Dot Matrix Display with MAX7219, DS3231 and DHT22
    https://www.youtube.com/watch?v=yEiVToSmaUA

     
    • Anobium

      Anobium - 2018-12-06

      Very nice!

       
    • Anobium

      Anobium - 2018-12-07

      Post the project code! Lots of folks are interested.

       
      • Awais

        Awais - 2018-12-07

        Thanks for your comments. Here is the code. Please add this to demo codes in next release of GCB.

        '''A demonstration program for Great Cow Basic.
        '''--------------------------------------------------------------------------------------------------------------------------------
        '''This program shows Time, Date, Temperature and Humidity on MAX7219 Dot Matrix Display using Arduino Nano, DS3231 and DHT22.
        '''Credit goes to Great Cow Basic Team
        '''@author  Owais Najam
        '''@licence GPL
        '''@version 1.0
        '''@date 6th Dec 2018
        ''' There is always room for improvement.
        '''********************************************************************************
        
        ; ----- Configuration
          #chip mega328p, 16
          #config MCLRE=on
          #include <max7219_ledmatrix_driver.h>
          #include <dht.h>
          #include <ds3231.h>
          #include <i2ceeprom.h>                  ; memory chips: at24c32 (storage capacity 32k)
          #option Explicit
        
          #define    AT24C32  0xAE                  ;Eeprom address
        
        ; Define Hardware I2C settings
          #define HI2C_BAUD_RATE 100
          #define HI2C_DATA PORTC.4
          #define HI2C_CLOCK PORTC.5
          HI2CMode Master
        
        
        ; ----- Constants
          #define DHT_type    22
          #define DHT_PIN PORTD.2
        
          #define period      2 S             ;update period
        
          #define clocktype   1               ;0 is US or 1 is UK style
        
        
        ; ----- Constants
          'Set SPI pins for the Max7219
          #define Max7219_DI    portb.4    'pin12
          #define Max7219_DO    portb.3    'pin11
          #define Max7219_SCK   portb.5    'pin13
          #define Max7219_CS    portb.2    'pin10
        
          'Specifics for device configuration
          #define MAX7219_X_Devices 8
        
          Dim ALARM1TRACK, ALARM2TRACK as Byte
          Dim CENTURY_FLAG, POWERLOSS, EEPROMVAL, DAYSMAX, DAYSMAX as Byte
          dim changed as bit
          dim hour, min, sec, am_pm as byte
          dim oldsec as byte
          dim date, month, year, DOW, century as byte
          dim mode, Oldmode, dayMax as byte
          oldsec = 255                        ; init value
          century = 20                        ; will be updated by Century calculation... if a century roll ever occurs!! Required in this example code.
        
          dim myString as string * 50
          Max7219_LEDMatrix_Brightness ( 0 )
        
        ;----- Tables
        
          table monthDays                     ;# of days in months. Required in this example code.
            31
            29                                ;leap years only
            31
            30
            31
            30
            31
            31
            30
            31
            30
            31
          end table
        
        
        '; ----- Main body of program commences here.
        
        
        
        
        ; ----- Define Hardware settings
        
        
        ; ----- Variables
        
          'required for DHT
          dim msg, whole, tenths as byte
          dim rh, cels, fahr as integer
        
        ; ----- Quick Command Reference:
        ;       The humidity and temperatures are signed integers, the error
        ;       indicator a byte. For the DHT11, the numerical results are
        ;       simply whole numbers. For the DHT22 numerical results
        ;       are fixed pointed numbers, with the decimal point assumed one
        ;       digit from the right. In other words, the values are scaled up
        ;       by 10. For example, a return value of 657 for the relative
        ;       humidity would be interpreted as 65.7%.
        
        ; ----- Main body of program commences here.
        
          GLCDCLS
          GLCDPrint (1, 0, "Wait...")
          Max7219_LEDMatrix_Update
          'let sensor stabilize
          wait period
        
          #ifdef HI2C_DATA
                ' GLCDCLS
                ' GLCDPrint (1, 0, "i2cHW" )
                ' Max7219_LEDMatrix_Update
                ' wait period
                HI2CReStart                          ; is DS3231 present?
                HI2CSend(DS_AddrWrite)
                HI2CStop
        
                if HI2CAckPollState = True  then  ; is DS3231 present?
                    GLCDCLS
                    GLCDPrint (1, 0, "No DS3231.." )
                    Max7219_LEDMatrix_Update
                    wait period
                    end
                end if
          #endif
        
          #ifdef I2C_DATA
                ' GLCDCLS
                ' GLCDPrint (1, 0, "i2cSW" )
                ' Max7219_LEDMatrix_Update
                ' wait period
                I2CStart                          ; is DS3231 present?
                I2CSend(DS_AddrWrite)
                I2CStop
        
                if I2CSendState = False  then     ; is DS3231 present?
                    GLCDCLS
                    GLCDPrint (1, 0, "No DS3231.." )
                    Max7219_LEDMatrix_Update
                    wait period
                    end
                end if
           #endif
        
        
          DS3231_ReadDate(DOW, date, month, year, century_flag )   ;get initial date
          if century_flag = 1 then
             DS3231_HandleCentury ( century_flag, Century )
          end if
        
          DS3231_ReadHourMode(mode)                 ;and the current mode
          DS3231_SetHourMode(12)                  ;update hour mode from RTC
          DS3231_EnableOscillator( true )           ;and, ensure the clock is running
        
          ;
          ;Example of configuration of the 32K output and the SQW
          ;
          DS3231_Set32kHz ( true )                  ;and, enable the 32kHz Output (EN32kHz).
          DS3231_EnableSQW
          DS3231_SetSQW 0                           ;and, turn ON output as we will use as the alarm port!
          DS3231_DisableSQW
        
        
        
        
          do
        
              DS3231_ReadDate(DOW, date, month, year, century_flag )   ;get initial date. This is required for main routine.
              if century_flag = 1 then
                DS3231_HandleCentury ( century_flag, Century )
              end if
        
              DS3231_ReadHourMode(mode)                 ;and the current mode
        
              ' initialise a tracking varaible
              powerloss = false
              dim EEpromAddress as word
              EEpromAddress = 0
        
              GLCDCLS
              updateDisp                        ;show time and date
        
              wait period
        
                'get current values
                readDHT(rh, cels, fahr, msg)
                GLCDCLS
                select case msg
                  'all okay, so proceed
                  case 0:
                    rh = rh / 10
                    cels = cels / 10
                    fahr = fahr / 10
                    myString = str(cels) + "/"
                    myString = myString + str(fahr) + " "
                    myString = myString + str(rh) + "%"
                    GLCDPrint (5, 0, myString )
                    Max7219_LEDMatrix_Update
                  'unit not responding
                  case 1:
                    GLCDPrint (1, 0, "No reply...")
                    Max7219_LEDMatrix_Update
                  'checksum error
                  case 2:
                    GLCDPrint (1, 0, "Bad CS...")
                    Max7219_LEDMatrix_Update
                end select
        
                wait period
          loop
          end
        
          sub printTime
            myString = ""
            'if mode = 24 then
              if hour < 10 then               ;left pad with zero
                myString = "0"
              end if
            'end if
            myString = myString + str(hour)
            myString = myString + ":"
        
            if min < 10 then                  ;left pad with zero
              myString = myString + "0"
            end if
            myString = myString + str(min)
            myString = myString + ":"
        
            if sec < 10 then                  ;left pad with zero
              myString = myString + "0"
            end if
            myString = myString + str(sec)
        
            if mode = 12 then                 ;Print a.m or p.m
              if am_pm then                   ;only in 12-hour mode
                myString = myString + "pm"
                GLCDPrint (2, 0, myString )
                Max7219_LEDMatrix_Update
              else
                myString = myString + "am"
                GLCDPrint (2, 0, myString )
                Max7219_LEDMatrix_Update
              end if
            end if
          end sub
        
        
        sub printDate
            myString = ""
            select case DOW                   ;day of the week
              case 1:
                myString = "Sun"
              case 2:
                myString = "Mon"
              case 3:
                myString = "Tue"
              case 4:
                myString = "Wed"
              case 5:
                myString = "Thu"
              case 6:
                myString = "Fri"
              case 7:
                myString = "Sat"
              case else
                myString = "Err"
            end select
        
            myString = ""
            if clocktype = 0 then
              myString = myString + str(month)
              myString = myString + "/"
        
              if date < 10 then                  ;left pad with zero
                myString = myString + "0"
              end if
        
              myString = myString + str(date)
              myString = myString + "/"                      ;make four-digit year
              myString = myString + str(century)
              if year < 10 then
                myString = myString + "0"
              end if
        
            else
              if date < 10 then                  ;left pad with zero
                myString = myString + "0"
              end if
        
              myString = myString + str(date)
              myString = myString + "/"
              myString = myString + str(month)
              myString = myString + "/"                      ;make four-digit year
              myString = myString + str(century)
              if year < 10 then
                myString = myString + "0"
              end if
            end if
            myString = myString + str(year)
        
            GLCDPrint (2, 0, myString )
            Max7219_LEDMatrix_Update
          end sub
        
        
          sub updateDisp
            ;for best efficiency, date is only updated once a day
            DS3231_ReadTime(hour, min, sec, am_pm)
            if oldsec <> sec then
              if !(hour | min | sec) then       ;time to update
                DS3231_ReadDate(DOW, date, month, year, century_flag )
                if century_flag = 1 then
                   DS3231_HandleCentury ( century_flag, Century )
                end if
              end if
        
              printTime                         ;show time
              wait period
        
              GLCDCLS
              printDate
              oldsec =  sec
            end if
          end sub
        

        Waiting for some more twists from the coding fellows.

        With kind regards,
        Awais

         
        • Anobium

          Anobium - 2018-12-07
           
          • Awais

            Awais - 2018-12-07

            Once again, thank you for your prompt consideration.

            One question, how can I edit the fonts or you can say alter the alphabets?

             
            • Anobium

              Anobium - 2018-12-07

              Pleasure, good to see someone using the software.

              As this is using the GLCD command set - you are using the GLCD fonts.

              I posted a demo how to do this. See you installation - ..\Demos\GLCD_Solutions\GLCD_Demonstration_of_adding_additional_Font_Solutions\GLCD_Adding_an_second_Font_16F886_for_KS0108@16.gcb

              The method is the same - essentially replace GLCDDrawChar with your routine and your tables - then you can edit away to your hearts content. :-)

              Leave glcd.h and the other .h files as is... use the method shown in the demo. It is SO easy to loose adapted .h files and using the method shown in the demo ensure your do not loose your good works.

               
              • Awais

                Awais - 2018-12-07

                Thanks. I will check.

                 
  • Awais

    Awais - 2018-12-08

    I didn't search the entire forum. Just found this utility "8x8 Pixel ROM Font Editor".
    https://www.min.at/prinz/o/software/pixelfont/

     
  • Anobium

    Anobium - 2018-12-08

    Regarding the degree "°" sign. I would not change the font. Simply pset the character out. So, pset the character out at the appropiate location using a table of the bits.

     
    • Awais

      Awais - 2018-12-08

      I did the following changes.

      dim xposition_degreesymbol as Byte
      |
      |
      |
      case 0:
                  rh = rh / 10
                  cels = cels / 10
                  fahr = fahr / 10
      
                  myString = ""
      
                  if cels < 10 then               ;left pad with zero
                    myString = "0"
                  end if
      
                  myString = myString + str(cels) + " C "
                  'xposition = (length_of_mystring - 3) * 5 + 8 + 3
                  xposition_degreesymbol = Len(myString)
                  xposition_degreesymbol = xposition_degreesymbol - 3
                  xposition_degreesymbol = xposition_degreesymbol * 5
                  xposition_degreesymbol = xposition_degreesymbol + 11
                  'myString = str(cels) + "/"
                  'myString = myString + str(fahr) + " "
                  myString = myString + str(rh) + "%"
                  'GLCDPrint (5, 0, myString )
                  GLCDPrint (8, 0, myString )
      
      
                  ' Print degree symbol
                  PSet(xposition_degreesymbol, 1, 1)
                  PSet(xposition_degreesymbol, 2, 1)
                  PSet(xposition_degreesymbol + 1, 0, 1)
                  PSet(xposition_degreesymbol + 2, 0, 1)
                  PSet(xposition_degreesymbol + 1, 3, 1)
                  PSet(xposition_degreesymbol + 2, 3, 1)
                  PSet(xposition_degreesymbol + 3, 1, 1)
                  PSet(xposition_degreesymbol + 3, 2, 1)
      
                  Max7219_LEDMatrix_Update
      

      And it's working.

      Thanks and regards,
      Awais

       
  • stan cartwright

    stan cartwright - 2018-12-08

    I suppose the font table used has a start address so 8 bytes per char, find start of char to change and design on paper and each pixel in a row is a bit.
    I'm guessing. I looked at glcd and #ifdef GLCD_OLED_FONT
    CharCode = CharCode - 16
    ReadTable OLEDFont1Index, CharCode, LocalCharCode
    ReadTable OLEDFont1Data, LocalCharCode , COLSperfont
    I would want to change all the chars to user designed graphics, there's plenty of program memory and ram to read a table into ram.

     
  • Anobium

    Anobium - 2018-12-08

    That is not way I would do it. As I am not guess.

    GLCD_OLED_FONT = 1 this reads the tables called OLEDFont1Index and OLEDFont1Data. Replacing this is one way.

    The real way - and the one that want to do is here: http://oleddisplay.squix.ch/#/home There is NOT reason why a simple converter could not read this font table and use the define fontset. With a simple converter any font could be used with this utility.

     
    • stan cartwright

      stan cartwright - 2018-12-08

      Since I have a few displays that have gcb support I should have already tried udgs but...etc.
      I last changed a charset on a sinclair or amstrad but I suppose it's the same idea.
      The char set was in rom but there was an address you could change to point to ram so you designed another char set in ram. So print "a" would print the "a" in ram.
      Is this the basic idea using gcb. Ie the char set is stored somewhere and the start is known, each char is 8 rows of 1 byte and each byte represents 8 pixels/leds?
      Is connecting two displays to use as a 16x32 possible with gcb...or any system?
      Cheers.

       
1 2 > >> (Page 1 of 2)

Log in to post a comment.