November 29, 2024, 03:20:24 AM

News:

Be sure to checkout our Vixen interfaces in the Library forum -- if you want PC automation at near zero cost, EFX-TEK and Vixen is a great combination of tools.


How to setup and read and write to variables in a other cog (processor)

Started by bsnut, January 06, 2016, 01:11:22 AM

Previous topic - Next topic

bsnut

I am having some trouble reading and writing to variables in this code when lunched into another cog.

{ This is auto-generated code from PICoPLC. Do not edit this file! Go
   back to the ladder diagram source for changes in the logic, and compile }

CON

CycleTime = 100 '1/sec
var
BYTE I_mcr
var
BYTE I_rung_top
var
BYTE I_parOut_0000
var
BYTE I_parThis_0000
con
U_Xbutton1 = 0
var
WORD U_Tdon
con
U_Xbutton2 = 1
var
BYTE I_Tdof_antiglitch
var
WORD U_Tdof
var
BYTE U_Rchatter
con
U_Yred = 8
var
WORD U_Ton
var
BYTE I_Tnew_antiglitch
var
WORD U_Tnew

PRI PlcCycle | timing

  timing := cnt + clkfreq / CycleTime
  repeat
    I_mcr~~
   
    { start rung 1 }
    I_rung_top := I_mcr
   
    { start series [ }
    { start parallel [ }
    I_parOut_0000~
    I_parThis_0000 := I_rung_top
    { start series [ }
    { Contact }
    ifnot (in[U_Xbutton1])
      I_parThis_0000~
   
   
    { TON element }
    if (I_parThis_0000)
      if (U_Tdon < 99)
        U_Tdon++
        I_parThis_0000~
     
    else
      U_Tdon := 0
   
   
    { ] finish series }
    if (I_parThis_0000)
      I_parOut_0000~~
   
    I_parThis_0000 := I_rung_top
    { start series [ }
    { Contact }
    ifnot (in[U_Xbutton2])
      I_parThis_0000~
   
   
    { TOFF element }
    ifnot (I_Tdof_antiglitch)
      U_Tdof := 199
   
    I_Tdof_antiglitch~~
    ifnot (I_parThis_0000)
      if (U_Tdof < 199)
        U_Tdof++
        I_parThis_0000~~
     
    else
      U_Tdof := 0
   
   
    { ] finish series }
    if (I_parThis_0000)
      I_parOut_0000~~
   
    I_rung_top := I_parOut_0000
    { ] finish parallel }
    { Negated contact }
    if (U_Rchatter)
      I_rung_top~
   
   
    { Normal coil }
    out[U_Yred] := I_rung_top
   
    { ] finish series }
   
    { start rung 2 }
    I_rung_top := I_mcr
   
    { start series [ }
    { Negated contact }
    if (U_Rchatter)
      I_rung_top~
   
   
    { TON element }
    if (I_rung_top)
      if (U_Ton < 99)
        U_Ton++
        I_rung_top~
     
    else
      U_Ton := 0
   
   
    { TOFF element }
    ifnot (I_Tnew_antiglitch)
      U_Tnew := 99
   
    I_Tnew_antiglitch~~
    ifnot (I_rung_top)
      if (U_Tnew < 99)
        U_Tnew++
        I_rung_top~~
     
    else
      U_Tnew := 0
   
   
    { Normal coil }
    U_Rchatter := I_rung_top
   
    { ] finish series }
    waitcnt(timing)
    timing += clkfreq / CycleTime

The I/O variables I want to read and write to are these.

in[U_Xbutton1] 'ttl input pin
out[U_Yred] ' output pin

The goal is to make the "Main" part of the code cleaner and easier to read.
William Stefan
The Basic Stamp Nut

JonnyMac

Wow... my eyes just exploded out of my head! The goal of a programming language is to make a program EASIER for humans to understand, not harder.

Please explain -- in PLAIN ENGLISH -- what that code is doing and I'll show you how to write it in native Spin which will probably be far cleaner and far more efficient. By its nature Spin lends itself to ladder type programming.

Just a tip: Not only are the post set (~~) and clear (~) operators a mystery to everyone, they actually take more time to run than the more obvious:

  somevar := -1
  somevar := 0


If -1 seems odd, $FFFFFFFF is the same value in hex.
Jon McPhalen
EFX-TEK Hollywood Office

bsnut

Quote
Wow... my eyes just exploded out of my head! The goal of a programming language is to make a program EASIER for humans to understand, not harder.
That's what I said when I first saw it compiled into spin.
Quote
Please explain -- in PLAIN ENGLISH -- what that code is doing and I'll show you how to write it in native Spin which will probably be far cleaner and far more efficient. By its nature Spin lends itself to ladder type programming.
What this code does is. When you push one of the buttons on TTL pin 0 for 1 second or TTL pin 1 for 2 seconds and do not release these buttons it will flash (1 sec off and 1 sec on) the output on pin 8.
Quote
Just a tip: Not only are the post set (~~) and clear (~) operators a mystery to everyone, they actually take more time to run than the more obvious:

  somevar := -1
  somevar := 0

If -1 seems odd, $FFFFFFFF is the same value in hex.
Now, I see why my code didn't work and it makes since too me now. My bad for not reading the Propeller manual. It shows what you are talking about :-[

I think the person who designed the code generator found easier to type "~~" for post set and "~" for clear instead of typing "-1" for post set and for "0" clear.
William Stefan
The Basic Stamp Nut

JonnyMac

Had you hired me to write that program, this is what I would have delivered. I know that ladder programming is still favored by some that do industrial control, but I submit that Spin -- especially with synchronized (fixed timing) loops -- is easy to set up for industrial processes. Some years ago I helped a company with a networked HVAC system that worked really well. They were skeptical of Spin at first, but Parallax convinced them to speak with me and once I showed them how (and wrote the master controller), they picked up and created their own apps for a solar tracker and chilling tower.

I think this code is easier to deal with (I've attached an archive so you can run it).

pub main | t
                                                                 
  setup                                                         ' setup io and objects

  t := cnt                                                      ' sync timing                                                           
  repeat
    waitcnt(t += LOOP_TIX)                                      ' run at loop timing
    process_sensor1   
    process_sensor2
    update_flasher 


pub process_sensor1

  if (ttlpins & SENSE1)                                         ' sensor active?
    s1timer += LOOP_MS                                          ' yes, update timer
    if (s1timer => 1000)                                        ' threshold reached?
      fstate |= %01                                             ' yes, set s1 state bit
  else
    s1timer := 0                                                ' reset timer
    fstate &= %10                                               ' clear s1 state bit     


pub process_sensor2

  if (ttlpins & SENSE2)                                         ' sensor active?
    s2timer += LOOP_MS                                          ' yes, update timer
    if (s2timer => 2000)                                        ' threshold reached?
      fstate |= %10                                             ' yes, set s2 state bit
  else
    s2timer := 0                                                ' reset timer
    fstate &= %01                                               ' clear s2 state bit


pub update_flasher

  if (fstate == %00)                                            ' if neither sensor qualified
    pwm.low(FLASHER)                                            ' clear flasher
    f0timer := 1000                                             ' force immediate "on" flash
  else
    if (pwm.read(FLASHER))                                      ' on?
      f1timer += LOOP_MS                                        ' update on timer
      if (f1timer => 1000)                                      ' done?
        pwm.low(FLASHER)                                        ' yes, lamp off
        f0timer := 0                                            ' reset off timer
    else                                                        ' off
      f0timer += LOOP_MS                                        ' update off timer
      if (f0timer => 1000)                                      ' done?
        pwm.high(FLASHER)                                       ' yes, lamp on                                       
        f1timer := 0                                            ' reset on timer     



The important lesson here is that the code is highly modular. If you want to change the behavior of a sensor it's easy to find. What to and another sensor? Follow the modular pattern and your code will be easier to follow.

Beware long chunks of code -- they are very hard to follow and troubleshoot.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

Forgot to mention that I coded the flasher such that the lamp could have different on- and off- times -- with a bit more work you could modify the flashing such that you'd know which or if both inputs was active.
Jon McPhalen
EFX-TEK Hollywood Office