Menu

Assigning different PORT to one same variable

Flotul
2024-08-01
2024-08-06
  • Flotul

    Flotul - 2024-08-01

    Hi All,

    I'm wondering if it is possible to assign a different PORT to a same variable like this example

    IF Value = 1 THEN
        PortPin = PortA.0
    ELSE
        PortPin = PortA.1
    END IF
    

    Is this doable in GCB?

     
  • Anobium

    Anobium - 2024-08-01

    Well yes.

    But, so points though.

    if PortPin is a constant. If the constant is a port.pin the will be assigned the bit value of porta.x
    If PortPin is a bit variable. It will assigned to bit value of porta.x
    If PortPin is a byte variable. It will be assigned 1 or 0 that is the value of porta.x

    Compile a program and try. See what happens.

     
  • Chris Roper

    Chris Roper - 2024-08-01

    what about:

    IF Value = 1 THEN
    PortPin = 0
    ELSE
    PortPin = 1
    END IF

     
  • Flotul

    Flotul - 2024-08-01
    IF Value = 1 THEN
    PortPin = 0
    ELSE
    PortPin = 1
    END IF
    

    This code obviously only changes the port's state which is not what I'm looking for.

    I'm currently looking into Anobium's advice....

     
  • Flotul

    Flotul - 2024-08-01

    Anobium,

    I'm starting with GCB so my knowledge of its syntax is not that great for the moment.

    #chip 18F1330, 40
    #Define NeoPin   PORTB    ' this is should be a Constant, right?
    Dim Idx As Byte
    Idx = 0
    Do
        NeoPin.Idx = 1
        Wait 500 ms
        NeoPin.Idx = 0
        Wait 500 ms
    Loop
    

    This is my code, not working.

    How do I declare a port pin as "variable"? I don't know how to declare it as a bit, btw...

    I'm a little confused here.

     
  • Flotul

    Flotul - 2024-08-01
     

    Last edit: Flotul 2024-08-01
  • Anobium

    Anobium - 2024-08-01

    You need to set the DIRection of the port.

    Dir NeoPin Out

    And, yes.. you created a CONSTANT.


    Your code is highly costly in terms of program memory. Whilst you may not know IDX bit value there are many ways to make this better.

    #chip 18F1330, 40
    #Define NeoPin   PORTB    ' this is should be a Constant, right?
    
    Dir NeoPin Out
    
    Dim Idx As Byte
    Idx = 0
    Do
        NeoPin.Idx = 1
        Wait 500 ms
        NeoPin.Idx = 0
        Wait 500 ms
    Loop
    

    You can read the port into a varaible and set the variable.bit and then set the port.
    Use a select Case.
    Read the port and rotate to set the bit. The hardest to understand, the fastest.
    There are other waysm but the above method works but is slow.

     
  • Chris Roper

    Chris Roper - 2024-08-01

    This is probably the fastest loop:

    Do
    neopin=!Neopin
    Wait 500 ms
    Loop

     
    👍
    1
  • Flotul

    Flotul - 2024-08-03

    Thanks Chris but this is still not what I'm asking for.

    So, looking back to my first post, I could have asked otherwise like this:

    Dim PortPin as Byte ' this variable is ment to represent a PORT
    
    If a condition is true Then
        Light up the LED on i.e. PortPin = PORTA.0
    Else
        Light up the LED on i.e. PortPin = PORTC.4
    Endif
    
    SubRoutine:
    Do
        neopin=!Neopin
        Wait 500 ms
    Loop
    

    Is it a little more clear now? Actually, I can't make that work.

    Again, to avoid the need of copying tons of code, I have made one subroutine where I then set the needed port.

     
  • Chris Roper

    Chris Roper - 2024-08-03

    Now that I have a better understanding of your intent, I can see that you are on totally the wrong track.

    All you are doing is assigning a value to a variable called portpin.

    What you are attempting to do is assign a value, that is the address of a port, to a variable called portpin and then use that variable to indirectly address a bit within that port.

    In short It can't be done in GCBasic in the way that you thought, however, you can work around it in GCBasic by embedding assembler code into your basic code to indirectly address the hardware.

    You will lose all portability, and will have to have a good understanding of the Datasheet for the device you are trying to program, but it can be done.

    You may also want to try the Help pages and look for Indirect addressing, you may find some answers there which could alleviate the burden of assembly programing.

    Cheers
    Chris

     
  • Anobium

    Anobium - 2024-08-03

    Guys.

    This code needs way more clarification before ASM is needed.

    ~~~
    Dim PortPin as Byte ' this variable is ment to represent a PORT

    If a condition is true Then
    PortPin = PORTA.0
    Else
    PortPin = PORTC.4
    Endif

    Sub mySub
    Do
    neopin=!Neopin
    Wait 500 ms
    Loop

    End Sub
    ~~~~

    What is actually meant to happen?

    if some condition is true then the Byte variable is meant to be what? is bit.0 meant to be the state of porta.0 or portc.4 ? or, is variable meant to be 0 or 255? should this be PortPin as a Bit? should this be PortPin.0?

    What is happening in the sub? Some other ram register or some other io register is toggling? What has this to with solution as this is an endloop?

     
  • Flotul

    Flotul - 2024-08-03

    I actually opened another thread about #Include/#Insert but it is all for the same project.

    So please find here my project and it might help to understand why I'm currently doing the way...it is done. @20MHz, there is a huge timing issue (meaning there is no space at all for GOSUBs, GOTOs et so forth) using the WS2812B NeoPixel strings reason why I have some ultra simple assembler code in it.

    My wall clock has four digits made of each a NeoPixel string (4x 28 piexels). Each string is connected to a different port (i.e. PORTA.0, PORTA.1, PORTA.2 and PORTA.3 )

    Currently, I can address one string (one PORT) and the code works...for one string. I cannot make three more copies of the code in my PIC. Instead, if I could address all four ports by the help of a variable (all other possible solution), my clock would already be hanging on my wall.

    Hope this helps to slightly getting something to see through the mist...

    https://sourceforge.net/p/gcbasic/discussion/579125/thread/c9bfa9bf93/1d24/attachment/WS2812B_18F1330_A.zip

     
  • Ccin E Crout

    Ccin E Crout - 2024-08-03

    I would be tempted to use one pin as the output and then feed that into the anodes of four diodes with the cathodes of those four diodes connected to a set of four 470R resistors. The junctions of the diodes/resistors fed to your WS2812B's and the 'free' end of the resistors connected to four additional pins on the PIC. By setting one of the relevant pins low, that output will go high/low as the code sets the output for the WS2812B, with all three of the other pins set high, those connections to the WS2812B will stay high and not send any data. A simple diode multiplexer.

    Worth a try?

     
  • Flotul

    Flotul - 2024-08-04

    Thanks Ccin E Crout , why not?

    The downside here is the "loss" of one port but that might be the cost it takes.

     
  • Anobium

    Anobium - 2024-08-04

    It seems that #include WILL NOT do what you want. See later in this post.

    Use the work around attached. This uses two macros to do the same, I have made this compile but this will be a lot easier to get going.

    I have added 32mHz to the frequency, I am not sure if you have tested on real silicon but you would need to add the correct CONFIG statements for 40Mhz.

    I also removed the #ASMRAW as this is not required and was incorrect used anyway.


    A few things other things I would do.

    Change the chip to a modern chip that is a lot faster.
    Use the demo demos\LED_Solutions\LED_WS2812\WS2812_LED_using_BitBanging-18f14k22.gcb this will then remove the reliance on NOPs and move to a proper time based interrupt solution.
    This demo will remove the reliance on have to populate the arrays NeoGreen(), NeoBlue() and NeoRed() as this is very slow.
    WS2812B_18F1330_C.gcb works. I get that but I think the demo is a lot faster and using WS2812BitBangSendData to improve performance.
    Do a search on YouTube for GCBASIC | Great Cow BASIC and WS2812. MKStevo, myself and others have posted using the libraries in the demo.
    https://www.youtube.com/watch?app=desktop&v=HX5B5dytBzM


    Why Include did not work in this very specific case = unstructured code

    In GCBASIC, any code that is not placed within a structure like a subroutine, function, or macro will not be compiled because the compiler expects all executable code to be organized within these structures. This design ensures that the code is modular, maintainable, and easier to debug.

    Here are a few reasons why this approach is used:

    1. Modularity: By requiring code to be within subroutines, functions, or macros, GCBASIC promotes modular programming. This makes it easier to manage and understand the code, especially in larger projects.

    2. Scope Management: Placing code within structures helps manage variable scope effectively. None byte variables declared within a subroutine or function are scoped to that block, preventing unintended interactions with other parts of the program.

    3. Error Handling: Structured code allows for better error handling and debugging. If an error occurs, it is easier to trace and fix within a well-defined block of code.

    4. Reusability: Functions and macros can be reused throughout the program, reducing redundancy and making the code more efficient.

    Essentially, the code within WS2812B_18F1330_B.gcb and WS2812B_18F1330_C.gcb is not structured, never called and therefore removed from the end to end program when your program is optimised.

    This can be proved with your sources.
    Editing file A to call a macro defined in file B 'macroB'
    Editing file B to
    Leave one #include
    Edit all calls to #INCLUDE "WS2812B_18F1330_C.gcb" to be MacroC
    Top and tail fileB with the macro definition for 'macroB'
    Edit file C
    Top and tail fileC with the macro definition for 'macroC'

    Now... you will try to compile and you will get a syntax error, so, edit out all the #RAWASMs.

    It should compile.

     

    Last edit: Anobium 2024-08-04
  • Anobium

    Anobium - 2024-08-04

    This is a very interesting use case.

    Thank you for posting the source. I now understand what is going on.

    :-)

    Evan

     
  • Flotul

    Flotul - 2024-08-05

    Thanks a lot Evan.

    As I'm a little short in time, I made my proto this week-end using five separate µCs, one as MASTER and four as SLAVEs (see pictures).

    I even used my crapy code but, at the end of the day, it works.

    And thank you for explaining the use of GCB. I'm new to it so I have a lot to discover.

     
    ❤️
    1
  • Anobium

    Anobium - 2024-08-05

    Looks great.

    I am interested in seeing final program. Please share.

     
  • Flotul

    Flotul - 2024-08-06

    I will do...but it will still be in PICBASIC for now...

     

Log in to post a comment.