Shop OBEX P1 Docs P2 Docs Learn Events
Can two cogs within the same obect have access to the same global variable? - Page 2 — Parallax Forums

Can two cogs within the same obect have access to the same global variable?

2

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-15 18:39
    I just did some experiments - yes, as PhiPi says, global variables are updated if altered by other parts of the program.

    There are still other possibilities. Questions about the hardware too. I can't test this as I don't have a keypad. Please send through your updated test code.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 18:42
    Okay I got it to work by commenting out some code, now I need to study it to unerstand why. I will be back.
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 18:44
    Hi Bruce.

    I post slightly edited Code that previous.
    Read all my comments in it ---> I can't say I not understand You code --- But as usually every people/programmer have different approach how it can be done.
    I can't say even that My one are better else bad. It is my logical solution to it NO more.

    idbruce wrote: »
    Alright

    Here is another sample with FullDuplexSerialPlus instead of LCD display. It is not operating correctly. Baud rate is set correctly, but funny characters show up in the terminal window.

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 18:55
    Sapieha
    The keyboard in it's own cog is an absolute necessity.
    1. The initial thread is also a necessity
    2. WAITPEQ and WAITPNE are not the same function
    Bruce
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 19:11
    Hi Bruce.

    Sorry for "WAITPEQ and WAITPNE are not the same function" comment --- BUT as You see I not commented this line only added extra comment was unsure by my to!.

    Post slightly edited Code that use Instead CALL to PUB MonitorKeypad for test possibility's.

    The initial thread is also a necessity
    Only if You need after this part functioning more code in it! else waste of COG.

    As I said for possibility to test on my end this code I need Schematics to Yours "Keypad"
    As LCD I can use My LCD TV.

    idbruce wrote: »
    Sapieha


    1. The initial thread is also a necessity
    2. WAITPEQ and WAITPNE are not the same function
    Bruce
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-15 19:12
    Changed a few things but at least this works

    commented out waitpeq
    also commented out 'TimeDisplayCog := cognew(DisplayTimeAndDate, @TimeDisplayStack) + 1

    this is the problem I talked about earlier where two methods are trying to output to the serial port at the same time. So you have to work out some way of only having one talk at once, even when debugging.

    Also I ran this at 38400 baud but it should run at 115200
    CON
      _CLKMODE      = XTAL1 + PLL16X                        
      _XINFREQ      = 5_000_000
    OBJ
      Debug : "FullDuplexSerialPlus"  
    VAR
      BYTE Time
      BYTE Date
      LONG TimeTrackStack[32]
      LONG TimeDisplayStack[32]
      LONG KeypadCheckStack[32]  
      LONG PressedKey
      LONG KeyPressed  
      LONG AbleToStopExample
      LONG Reset
      LONG ClockIsSet
      BYTE TimeTrackCog
      BYTE TimeDisplayCog
      BYTE KeypadCheckCog  
    PUB BareBones
      Debug.Start(31, 30, 0, 38400)
      debug.str(string("start"))
      WAITCNT(CLKFREQ * 2 + CNT)
    
      KeyPressed := FALSE
      AbleToStopExample := FALSE
      Reset := FALSE
      Debug.Str(STRING("cognew"))   
      KeypadCheckCog:= cognew(MonitorKeypad, @KeypadCheckStack) + 1  
      TimeTrackCog := cognew(TrackTimeAndDate, @TimeTrackStack) + 1
      'TimeDisplayCog := cognew(DisplayTimeAndDate, @TimeDisplayStack) + 1
      AbleToStopExample := TRUE  
    
      REPEAT
        IF Reset == TRUE
          COGSTOP(KeypadCheckCog~ -1)      
          WAITCNT(CLKFREQ * 3 + CNT)
          REBOOT
    PUB MonitorKeypad | k
      DIRA[0..3]~  
      DIRA[5]~
      REPEAT
        'WAITPEQ(|<5, |<5, 0)
        KeyPressed := TRUE    
        PressedKey := INA[3..0]
        debug.str(string("press a key eg 8"))
        k:= debug.rx
        debug.tx(k)
        if abletostopexample == true
          debug.str(string("true"))
        else
          debug.str(string("false"))  
        IF k == "8" AND AbleToStopExample == TRUE 
          COGSTOP(TimeTrackCog~ -1)
          COGSTOP(TimeDisplayCog~ -1)
          Debug.Str(STRING("End Of Test"))
          Debug.Tx(13)
          Debug.Str(STRING("Goodbye"))
          Reset := TRUE 
          QUIT
        'WAITPNE(|<5, |<5, 0)    
    PUB TrackTimeAndDate | TimeResultString, DateResultString, AddOnString
      REPEAT
        Time := STRING("Time")
        Date := STRING("Date")
    PUB DisplayTimeAndDate
      REPEAT    
        Debug.Str(Date)
        Debug.Tx(13)
        Debug.Str(Time)
        Debug.Tx(13)
    
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 19:13
    It is a necessity because I need the keypad in its own cog
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 19:18
    Dr_Acula

    I did the same and that got it to work in Parallax Serial Terminal but not on the machine. The code represents that input is available from the keypad. It then obtains the bits on pins 0..3 to obtain the information about the key that was pressed.

    That is not the solution.

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 19:22
    I think the LCD needs a delay. That is my next attempt to fix the problem.
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 19:25
    Hi Bruce.

    If after initiating all things and no more need be run in COG-0 You add REPEAT before CALL to PUB MonitorKeypad it will run in its OWN COG = 0 that after all initiated are not used for any other thing

    idbruce wrote: »
    It is a necessity because I need the keypad in its own cog
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 19:28
    Sapieha

    This is not the complete code. It is the code for a machine interface. More code will be added to the first function. Therefore it is necessary.

    Bruce
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-15 19:34
    I did the same and that got it to work in Parallax Serial Terminal but not on the machine.

    Well then we are getting closer to the problem. The LCD display or the keypad.

    Can you rewrite code so that it sends to both the LCD and the terminal at the same time? That will check the LCD.

    Then test the keypad. I presume you have a one line bit of code that tests the keys actually work?
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 19:45
    Hi Bruce.

    Good point --- It was one of questions in my comments to Yours code.

    1. Code You need add --- are it ONE time code else need RUN repeated to.
    2. For test possibility's of this part of code I think not necessary --- As I can see it You have REPEAT --- IF RESET at last in this function ----> Give same function as.
    ' CALL to MonitorKeypad PUB.
      REPEAT
        MonitorKeypad
    
      
    [COLOR=green]{  MOVED to MonitorKeypad (Spare one COG) else never used.
    
    [/COLOR] [COLOR=green]   REPEAT
        IF Reset == TRUE
          COGSTOP(KeypadCheckCog~ -1)      
          WAITCNT(CLKFREQ * 3 + CNT)
          REBOOT
    }[/COLOR]
    
    idbruce wrote: »
    Sapieha

    This is not the complete code. It is the code for a machine interface. More code will be added to the first function. Therefore it is necessary.

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-15 20:00
    Sapieha

    While I appreciate your effort and enthusiasm, I am getting tired of explaining. The MonitorKeypad must run in its own cog and the first function must call it and also stay alive till the machine is shut down.

    Reboot will work in the location that you suggest, however it should not be necessary to move it.

    Bruce
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 20:06
    Hi Bruce.

    In my logical thinking to move RESET to PUB MonitorKeypad I have some errors.
    Look at this mod
    [B]PUB[/B] MonitorKeypad                 [COLOR=teal] ' Even this line not nessesary IF COG-0 only used after starting LCD [/COLOR]and
    '                                      other COG's for only this part of program.
    
      DIRA[0..3]~                        [COLOR=red]( Bad comment )' RUN's in COG-0 no need to waste COG for it [/COLOR]
      DIRA[5]~                 [COLOR=teal]' For functioning in COG-0 this 2 lines need be moved to Init part of start function[/COLOR]
    [COLOR=green]                                ' that give it start at once
    '  REPEAT         NEED be commented out
    [/COLOR]    WAITPEQ(|<5, |<5, 0)
        KeyPressed := TRUE    
    
    
    
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 20:15
    Hi Bruce.

    Now I'm confused ---- > WHY waste ONE COG for that last part of function in attached code if it is only thing after initializing all other things in First part of function are done (ONCE).
    As after initializing that first part of this function it will be only thing this COG will stay in (FOREVER before reset Propeller)
      REPEAT
        IF Reset == TRUE
          COGSTOP(KeypadCheckCog~ -1)      
          WAITCNT(CLKFREQ * 3 + CNT)
          REBOOT
    
    idbruce wrote: »
    Sapieha

    While I appreciate your effort and enthusiasm, I am getting tired of explaining. The MonitorKeypad must run in its own cog and the first function must call it and also stay alive till the machine is shut down.

    Reboot will work in the location that you suggest, however it should not be necessary to move it.

    Bruce
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 20:35
    Hi Bruce.

    You said "enthusiasm" ----> Maybe You have readed in icon1.pngCNC Machines

    That I to sample parts for my little ----> Personal CNC that I even have posted Picture on control panel I will use on it. That one is from old Epson stylus SX610FW.
    And Yours Program/Experience in it will help even me.

    idbruce wrote: »
    Sapieha

    While I appreciate your effort and enthusiasm, I am getting tired of explaining. The MonitorKeypad must run in its own cog and the first function must call it and also stay alive till the machine is shut down.

    Reboot will work in the location that you suggest, however it should not be necessary to move it.

    Bruce
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-15 21:12
    Thinking out loud - could it be hardware? I've just been through a forum search for the last few days but I can't see any schematics. My apologies in advance if you have already posted these. Any chance of a quick photo of the board and the schematic?
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-15 21:17
    Hi Bruce.

    I now looked on Yours original "MachineInterface.spin" code and it is how I approach this solution.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-16 08:25
    Hello Everyone

    This what I have determined through testing.
    1. The hardware is working fine. This was proven by outputing a string to the LCD without a new cog.
    2. The problem lies in the communication from a new cog to the LCD object.
    Please see the attachment below titled "AbosulteBareBones". This code does not work!

    Bruce
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-16 08:49
    Hi Bruce.

    Function for me - See attached files.


    idbruce wrote: »
    Hello Everyone

    This what I have determined through testing.
    1. The hardware is working fine. This was proven by outputing a string to the LCD without a new cog.
    2. The problem lies in the communication from a new cog to the LCD object.
    Please see the attachment below titled "AbosulteBareBones". This code does not work!

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-16 08:54
    Sapieha

    Again you are missing the point.

    1. The problem lies in the communication from a new cog to the LCD object.

    Therefore the problem lies in LCD : "LCD_16X2_4BIT"

    not

    LCD : "TV_Text"

    Bruce
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-16 08:58
    Hi Bruce

    I know that. But as I said to You I don't have that LCD to test this driver not Yours KB schematics to wire my test equipment.
    And test with thing's I have
    idbruce wrote: »
    Sapieha

    Again you are missing the point.




    Therefore the problem lies in LCD : "LCD_16X2_4BIT"

    not

    LCD : "TV_Text"

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-16 09:04
    Sapieha

    I am glad it worked for you.

    Bruce
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-01-16 09:11
    HI Bruce,

    as I don't have an LCD handy. Does it work without a cognew?
    I guess yes. I haven't followed all the postings in this thread but what jumps into my eyes is

    the str-method of LCD_16x2_4Bit.spin calls the method PRI CHAR (LCD_DATA)
    and inside this method some bitbanging is done.

    Now you put the call of the startmethod into the main-cog's code (cog 0)

    This means IO-Pins are set in the IO-register of cog 0
    PUB START  
    
      DIRA[DB7..DB4] := %1111                               ' Set everything to output              
      DIRA[RS] := 1
      DIRA[RW] := 1
      DIRA[E] := 1
    
      INIT 
    
    PRI INIT
    
      'DELAY.pause1ms(15)
      
      OUTA[DB7..DB4] := %0000                               ' Output low on all pins
      OUTA[RS] := 0
      OUTA[RW] := 0
    
      OUTA[E]  := 1
      OUTA[DB7..DB4] := %0010                               ' Set to DL=4 bits
      OUTA[E]  := 0
    
      INST4 (%0010_1000)                                    ' Now that we're in 4 bits, add N=2 lines, F=5x7 fonts                                              
      CLEAR
      INST4 (%0000_1100)                                    ' Display on, Cursor off, Blink off                                             
      INST4 (%0000_0110)                                    ' Increment Cursor + No-Display Shift                                             
    
    now you want to call the method string (char) from another cog. (cog 1)
    inside this cog the IO-register has no setup (because method start was called from cog 0)

    So for cog 1 the IO-pins are all still inputs and I guess that's the reason why nothing happens

    All IO-pin related stuff should be done by one and the same cog.

    Maybe it makes sense to think about a buffer-concept. There is one cog that does all the
    LCD-io by reading a buffer. This routine checks for bytes in the buffer that have changed and just
    send new if something has changed.

    All other cogs do NOT call the lcd-methods directly but only writing into the buffer.

    If I'm allowed to comment a bit more: You have done it the right way to narrow down the problem.

    I prefer to develop code VERY modular. one method is doing ONE thing or a couple of things
    but then they belong together closely. Then I test this modular piece of code to all strange kind of situations.
    (in case of LCD.str this would be call it with a string-pointer that is zero. call it with a VERY big
    string (more than double than the LCD can display at once), setting the cursor on the last char sending a big string etc.
    If all this works and catches up strange situations properly I'm going on with the next part of the code.
    This secures that a bug will be in the actual code (and not in a former piece of code) for 99% of all cases.

    best regards

    Stefan
  • idbruceidbruce Posts: 6,197
    edited 2011-01-16 09:23
    StefanL38

    Thank you so much for responding!
    So for cog 1 the IO-pins are all still inputs and I guess that's the reason why nothing happens

    All IO-pin related stuff should be done by one and the same cog.

    Maybe it makes sense to think about a buffer-concept. There is one cog that does all the
    LCD-io by reading a buffer. This routine checks for bytes in the buffer that have changed and just
    send new if something has changed.

    All other cogs do NOT call the lcd-methods directly but only writing into the buffer.

    I agree 100%. I believe this is the situation.

    For the sake of discussion. In the top object, I have two buffers named LCDLine1 and LCDLine2. Cog-0 should be the only cog allowed to communicate with the LCD object, whereas other cogs(1-7) are free to alter LCDLine1 and LCDLine2 at will. Am I correct to assume that this is what you are saying?

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-16 09:35
    StefanL38

    You were correct! That resolved the issue! THANK YOU VERY MUCH!

    Bruce
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-16 09:48
    Hi Bruce,

    if you do not run out of COGs you could try my LCD-driver. It's maybe a little bit harder to use as the driver does not have the usual comfort-functions, but the demo code added should show you how it works. The thing with this driver is, that you can set it up in a way that it's functioning like a screen-buffer. You can simply write the string into this buffer and "by magic" it appears on the LCD. Of course you can also have more than one screen-buffer and switch between.
    So, you could for example have one COG writing the time into a dedicated memory location of the screen-buffer. Another COG writes the coordinates of your machine to a different location ...

    It also includes a nice demo for a menu as far as I remember.

    Let me know if you need some help.

    http://obex.parallax.com/objects/576/
  • idbruceidbruce Posts: 6,197
    edited 2011-01-16 09:52
    MagIO2

    I like the way you described it. Sounds very nice. I'll check it out.

    Thanks
    Bruce
  • SapiehaSapieha Posts: 2,964
    edited 2011-01-16 10:00
    Hi MagIO2.

    It is possible You can change discussion Thread Link to new Forum.
    > http://forums.parallax.com/showthread.php?117059-Another-LCD-driver-%28HD44780%29
    MagIO2 wrote: »
    Hi Bruce,

    if you do not run out of COGs you could try my LCD-driver. It's maybe a little bit harder to use as the driver does not have the usual comfort-functions, but the demo code added should show you how it works. The thing with this driver is, that you can set it up in a way that it's functioning like a screen-buffer. You can simply write the string into this buffer and "by magic" it appears on the LCD. Of course you can also have more than one screen-buffer and switch between.
    So, you could for example have one COG writing the time into a dedicated memory location of the screen-buffer. Another COG writes the coordinates of your machine to a different location ...

    It also includes a nice demo for a menu as far as I remember.

    Let me know if you need some help.

    http://obex.parallax.com/objects/576/
Sign In or Register to comment.