Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using the IDE simulator (Oshonsoft).

DogFlu66

Member
Hi everyone!

We’re opening this special thread dedicated to sharing fully simulatable examples using the OshonSoft IDE, perfect for those who program in PIC Basic as well as for those who prefer working directly in assembler. The goal is to gather practices and projects that can be run entirely within the IDE’s built-in simulator, making the most of its powerful tools like the oscilloscope, virtual instruments, UART monitor, and other debugging aids that make OshonSoft a great platform for learning and rapid prototyping.

This thread aims to create a collaborative space where we can:
  • Share functional and educational code examples.
  • Demonstrate circuit behavior directly in the simulator.
  • Explore debugging and step-by-step verification techniques.
  • Fully leverage the IDE’s tools to understand how the microcontroller and its peripherals work.
It’s an ideal place for students, self-learners, and hobbyists who want to practice and learn without needing physical hardware.

Everyone is welcome to join!
Do you have an example to share? Want to simulate something but don’t know where to start? Jump in and let us know!

This thread is not intended to enter into a debate about which language or IDE is better, it is simply intended to have a fun time.
 
First we need a common configuration for the system:

Config Compiler.jpg
Config Compiler_01.jpg
Config Pic Simulator.jpg
Config Pic Simulator_01.jpg
Config Pic Simulator_02.jpg
Config Pic Simulator_03.jpg
 
Last edited:
I’m kicking things off with the recent addition of native support in version 5.83 of the compiler (in my case, for PIC18) for the PCF8574 I/O expander, which allows control of 16x2 and 20x4 LCDs via I2C communication. I'm including an example with the configuration setup and an image showing the result in the simulator.

I have added a function to be able to mix giant numbers on the display.

Code:
' PIC18F46K22 AND Lcd1602_I2C (PCF8574)
' By COS, 2025/04/16, PIC18 OSHONSOFT v5.83
' For simulation only.
' *************************************************************************************
' General configuration
#define CLOCK_FREQUENCY = 64  ' System clock frequency in MHz
#define SINGLE_DECIMAL_PLACES = 1  ' Number of decimal places for floating-point operations
#define STRING_MAX_LENGTH = 30  ' Maximum length for string variables
#define SIMULATION_WAITMS_VALUE = 0
' -------------------------------------------------------------------------
' -------------------------------------------------------------------------
' Main program
Main:
    '**********************************************************************
    AllDigital  ' Set all pins to digital mode

    ' Set all ports as input
    TRISA = 0xFF  ' Set all PORTA pins as input
    TRISB = 0xFF  ' Set all PORTB pins as input
    TRISC = 0xFF  ' Set all PORTC pins as input
    TRISD = 0xFF  ' Set all PORTD pins as input
    TRISE = 0xFF  ' Set all PORTE pins as input
    ' ---------------------------------------------------------------------
    ' Initialize UART at 115200 baud rate (using RC6 for TX and RC7 for RX)
    UART1_Init 115200
    WaitUs 1  ' Delay for stabilization
    ' ---------------------------------------------------------------------
    ' Send initial message through UART
    UART1_Write 0x0C  ' ASCII control character to clear screen
    WaitMs 100  ' Wait for 1 second
    UART1_Write "Ready", CrLf  ' Send "Ready" message with carriage return and line feed

    #define LCD_LINES = 4
    #define LCD_CHARS = 20
    '#define I2CCLOCK_STRETCH = 10
    #define LCD_MODE = lcdPCF8574
    #define LCD_SDA = PORTC.4
    #define LCD_SCL = PORTC.3
    #define LCD_D7 = 7
    #define LCD_D6 = 6
    #define LCD_D5 = 5
    #define LCD_D4 = 4
    #define LCD_BL = 3
    #define LCD_E = 2
    #define LCD_RW = 1
    #define LCD_RS = 0
    #define LCD_ADDR = 7
    WaitMs 50
    lcdPCF_BLhigh
    WaitMs 50

    Lcdinit LcdCurOff
    WaitMs 50

    Lcdout "LCD 20x4 I2C PCF8574"
    Lcdcmdout LcdLine4Home
    Lcdout "0123456789-ABCDEFGHI"
    WaitMs 500

    'WaitMs 500
    lcdPCF_BLlow
    WaitMs 500
    lcdPCF_BLhigh
    WaitMs 2000
    Lcdcmdout LcdCurOff

    Lcd_Out(3, 1, "Load GCRAM.")

    'User-defined characters (big number).
    Lcddefchar 0, %11111, %11111, %11111, 0, 0, 0, 0, 0  'Top horizontal bar.
    Lcd_Out(3, 6, ".")
    WaitMs 500
    Lcddefchar 1, 0, 0, 0, 0, 0, %11111, %11111, %11111  'Bottom horizontal bar.
    Lcddefchar 2, %11111, %11111, %11111, 0, 0, 0, %11111, %11111  'Top and bottom horizontal bar.
    Lcd_Out(3, 7, ".")
    WaitMs 500
    Lcddefchar 3, %11100, %11110, %11110, %11110, %11110, %11110, %11110, %11100  'Left column.
    Lcddefchar 4, %00111, %01111, %01111, %01111, %01111, %01111, %01111, %00111  'Right column.
    Lcd_Out(3, 8, ".")
    WaitMs 500
    Lcddefchar 5, 0, 0, 0, 0, 0, %00011, %00111, %01111  'Bottom Right arrow.
    Lcddefchar 6, %00011, %00111, %01111, 0, 0, 0, 0, 0  'Top Right arrow.
    Lcd_Out(3, 9, ".")
    WaitMs 500
    Lcddefchar 7, 0, 0, 0, 0, 0, %11000, %11100, %11110  'Bottom Left arrow.
    Lcd_Out(3, 10, ".")
    WaitMs 500

    Lcdcmdout LcdLine3Clear
    Dim counter As Integer
    counter = 0

    While True
        LCD_OutBigNum(2, 5, #counter + "ºC")
        'Lcdout " Temp."
        counter = counter - 1
        WaitMs 100
    Wend
End
'Function Lcd_Out(line, Xpos, String_Value)
Function Lcd_Out(Line As Byte, Xpos As Byte, txt[20] As String) As Bit
    Lcd_PosXY(Xpos, Line)
    Lcdout txt
End Function
'Function Lcd_PosXY(Xpos, Line)
Function Lcd_PosXY(Xpos As Byte, Line As Byte) As Bit
    If Line = 0 Then Line = 1
    If Line > 4 Then Line = 4
    If Xpos = 0 Then Xpos = 1
    Select Case Line
        Case 1
            Lcdcmdout LcdLine1Pos(Xpos)
        Case 2
            Lcdcmdout LcdLine2Pos(Xpos)
        Case 3
            Lcdcmdout LcdLine3Pos(Xpos)
        Case 4
            Lcdcmdout LcdLine4Pos(Xpos)
    EndSelect
End Function
' **********************************************************************
' Function that enlarges the numeric characters of a string
' Limited string length, written for 2-line
' Line: LCD line.
' Xpos: Starting position to print on the LCD
' strChar: numeric string to write.
' Returns the next position to print (low line).
' *********************************************************************
Function LCD_OutBigNum(Line As Byte, Xpos As Byte, strChar[20] As String) As Byte
    Dim dat As Byte    ' Mask
    Dim index As Byte      ' Index mask.
    Dim xStr As Byte          ' Character position of then string.
    xStr = 0
    While strChar(xStr) > 0
        Lcd_PosXY(Xpos, Line)    ' Lcd cursor position.
        For index = 0 To 5      ' Upper and lower mask print control loop.

            Select Case strChar(xStr)
                ' Numeric characters.
                Case "0"
                        dat = LookUp(4, 0, 3, 4, 1, 3), index            '0
                Case "1"
                        dat = LookUp(6, 255, " ", 5, 255, 7), index    '1
                Case "2"
                        dat = LookUp(6, 2, 3, 4, 1, 7), index            '2
                Case "3"
                        dat = LookUp(6, 2, 3, 5, 1, 3), index            '3
                Case "4"
                        dat = LookUp(4, 1, 255, " ", " ", 255), index    '4
                Case "5"
                        dat = LookUp(4, 2, 0, 5, 1, 3), index            '5
                Case "6"
                        dat = LookUp(4, 2, " ", 4, 1, 3), index        '6
                Case "7"
                        dat = LookUp(6, 0, 3, " ", 255, " "), index    '7
                Case "8"
                        dat = LookUp(4, 2, 3, 4, 1, 3), index            '8
                Case "9"
                        dat = LookUp(4, 2, 3, " ", " ", 255), index    '9

                ' Special characters.
                Case "º"
                        Lcdout "o"                                    'º
                        Lcd_PosXY(Xpos, Line +1)
                        Lcdout " "
                        Xpos++
                        Exit For
                Case "-"
                        Lcdout "_"                                    '-
                        Lcd_PosXY(Xpos, Line +1)
                        Lcdout " "
                        Xpos++
                        Exit For
                Case Else
                        Lcdout " "
                        Lcd_PosXY(Xpos, Line +1)
                        Lcdout strChar(xStr)
                        Xpos++
                        Exit For
            EndSelect

            'Write the numeric characters.
            Lcdout dat  'Print the current mask.
            If index = 2 Then
                Lcd_PosXY(Xpos, Line +1)  'Line change.
                Xpos = Xpos + 3  'Position of the new digit.
            Endif

        Next index

        xStr++  'Next digit to print.
    Wend
    ReturnValue Xpos 'Return to the next position.
End Function

LCD20x4_I2C_PCF8574_Simulator.jpg
 

Attachments

  • Test LCD1602 I2CLib_Simulator.bas
    6 KB · Views: 38
Last edited:
Thankyou, I will be following this thread.

This code will also run (in simulation) on a 16F1789 in the PIC16 version of the compiler (wont run on the Basic compiler - not enough stack levels in the base level PICs ).
 

Attachments

  • Test LCD1602 I2CLib_Simulator_16F1789.bas
    6 KB · Views: 32
Thankyou, I will be following this thread.

This code will also run (in simulation) on a 16F1789 in the PIC16 version of the compiler (wont run on the Basic compiler - not enough stack levels in the base level PICs ).
It works fine on the 16F1789, but on other microcontrollers with a smaller stack, stack problems may occur. A more simplified version would have to be made for it to work correctly. In any case, when something like this happens, it is advisable to report the problem because it helps them improve the system.
 
Interestingly - in respect to the simulation - the 16F88 version seems to run much faster, although I didn't change any of the compiler/simulator configuration options as above for this one.
 
' Initialize UART at 115200 baud rate (using RC6 for TX and RC7 for RX)
UART1_Init 115200
WaitUs 1 ' Delay for stabilization
' ---------------------------------------------------------------------
' Send initial message through UART
UART1_Write 0x0C ' ASCII control character to clear screen
WaitMs 100 ' Wait for 1 second
UART1_Write "Ready", CrLf ' Send "Ready" message with carriage return and line feed
I'm slowly going through the code to get the brain back in to Basic programming mode and hence a question re the above bit.

I assume you intended to spit info out a serial interface at some stage, as it appears to do nothing regards the I2C interface?
 
Yes, they're for debugging purposes, although the "watch variables" module also works very well for that. If it's faster, I assume it's because the microcontroller is simpler.
 
Pic16F88:
The function "LCD_Out(Line, Xpos, string)" modifying it in this other way allows it to be called from the main.

Code:
Function LCD_Out(Line As Byte, XPOS As Byte, strChar[20] As String) As Bit
    If Line = 0 Then Line = 1
    If Line > 4 Then Line = 4
    If XPOS = 0 Then XPOS = 1
    Select Case Line
        Case 1
            Lcdcmdout LcdLine1Pos(XPOS)
        Case 2
            Lcdcmdout LcdLine2Pos(XPOS)
        Case 3
            Lcdcmdout LcdLine3Pos(XPOS)
        Case 4
            Lcdcmdout LcdLine4Pos(XPOS)
    EndSelect

    Dim index As Byte
    index = 0

    While strChar(index) > 0
        Lcdout strChar(index)
        index++
    Wend
End Function
 
Last edited:
I do actually have a project (asm coded) that I would like to add the I2C display to, so this is somewhat timely.

My previous attempts at extracting the Oshonsoft assembler code and adding it in to an existing asm program have never been entirely successful for some reason.
 
I see we've been working in parallel! I took your original, many function code and with Vladimir Soso's addition of the OshonSoft PIC I2C support in v3.83, was able to reduce your functions to just the one, 'LCD_OutBigNum'. Works great! Thanks for your help in creating the data array and encouraging me to generate the code for my project.
 
I do actually have a project (asm coded) that I would like to add the I2C display to, so this is somewhat timely.

My previous attempts at extracting the Oshonsoft assembler code and adding it in to an existing asm program have never been entirely successful for some reason.
My assembly codes are only a few lines long so I can't help much.

I see we've been working in parallel! I took your original, many function code and with Vladimir Soso's addition of the OshonSoft PIC I2C support in v3.83, was able to reduce your functions to just the one, 'LCD_OutBigNum'. Works great! Thanks for your help in creating the data array and encouraging me to generate the code for my project.
I'm really glad to hear that the code is proving useful to you. I hope your project turns out to be a great success!
 
There are new improvements in the IDE for those using Pic Basic Compiler v9.84 (for PICs with eight stack levels). The driver has been optimized to control 1602/2004 displays via I2C using the PCF8574 I/O expander. It is now possible to make function calls within another function again.
I've attached the IDE configuration, although it should be enabled by default:

OshonSoft PIC Basic Compiler v984.jpg
 

Attachments

  • Test LCD1602 I2C_Simulator.bas
    6.2 KB · Views: 12
Last edited:

Latest threads

New Articles From Microcontroller Tips

Back
Top