May 18, 2024, 03:20:54 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.


Reading HC-8 TTL inputs

Started by bsnut, March 31, 2012, 03:25:39 AM

Previous topic - Next topic

bsnut

Jon,

I have a basic understanding how to read the TTL inputs and was wondering the reasoning behind the change in this method.

Pub ttl_inputs(rescan)

   If (rescan)
      lastscan:= in_165(16,MSBFIRST) ¦ ina[dmx_a8] <<16 ' read in0...in7
     
      return(lastscan & $ff)

I also realize that this method needs to be called every time when you need to look at the inputs.

Also can you provide an example or examples in reading multiple inputs from the shift register to help refresh my memory.
William Stefan
The Basic Stamp Nut

JonnyMac

I only changed the name; the internal code is the same.

Here's what's going on with ttl_inputs and dmx_address: the HC-8+ uses two daisy-chained shift-registers to read the TTL pins and the lower eight bits of the DMX switch (bit A8 is a direct connection to the Propeller).  When you call either of these methods with the parameter set to true, we read 16 bits (both shift registers) in and save those to a system variable called lastscan.  The individual elements are then extracted from lastscan.

From a practical standpoint you might do something like this:

  ttl := ttl_inputs(true)
  dmx := dmx_address(false)


The call to ttl_inputs forces a read of both shift-registers.  Since we've just scanned the shift registers we can call dmx_address with false to save a bit of time (i.e., by not re-scanning).

Have a look at the in_165 method; that's what's reading the inputs.  Note that we always call it with 16 bits because we have two shift registers in the chain and you want to ensure that you get all bits in the chain in the same read.
Jon McPhalen
EFX-TEK Hollywood Office

bsnut

QuoteHave a look at the in_165 method; that's what's reading the inputs.
I did noticed that Jon, I wasn't thinking that you had two shift-registers on the board.

I was wondering from your standpoint would it be practical to run another cog for this.

  ttl := ttl_inputs(true)
  dmx := dmx_address(false)

So I don't have to do this every time I need to read the shift-register inputs.

  ttl := ttl_inputs(true)
  if ttl == in1
    my_method
  ttl := ttl_inputs(true)
  if ttl == in2
    other_method_here

And do something like this in the main section of the code, which would save a lot of copying and pasting code and it would be easier to read.

  if ttl == trigger1
    my_method
  if ttl == in2
    other_method_here




William Stefan
The Basic Stamp Nut

JonnyMac

April 01, 2012, 12:25:51 PM #3 Last Edit: April 01, 2012, 12:27:40 PM by JonnyMac
You can certainly auto-scan the inputs in another cog but you have to be careful; it's not a matter of calling x165_in method from another cog -- you can't do this because each cog has it's own dira (pin directions register) and the original x165_in pins were was setup in a differnt cog.

Here's what I suggest.  In the demo that's attached (which is a modified version of the template) I changed the methods accessing digital inputs so that you don't have to manually scan.  Here's the updates for digital inputs:

pub ttl_inputs

'' Return TTL inputs status

  return digins & $FF                                           ' return TTL input pins


pub dmx_address

'' Return DMX address switch setting

  return (digins >> 8) & $01FF                                  ' return DMX address bits


pri scan_digins | t, work                                       ' start with cognew

  high(LD_165)                                                  ' setup x165 io pins
  low(CLK_165)
  input(DO_165)

  t := cnt                                                      ' synchronize loop timer
  repeat
    outa[LD_165] := 0                                           ' load inputs   
    outa[LD_165] := 1                                                                       
    work := 0                                                   ' clear workspace
    repeat 16                                                   ' read n bits         
      work := (work << 1) | ina[DO_165]                         ' get new bit             
      outa[CLK_165] := 1                                        ' blip clock             
      outa[CLK_165] := 0 
   
    digins := work | ina[DMX_A8] << 16                          ' add A8, write to hub
   
    waitcnt(t += (MS_001 * 5))                                  ' update every 5ms


Note that there x165_in is gone and replaced with scan_digins.  Note, too, that this method runs non-breaking, synchronized loop.  What this means is that we cannot call this method like a regular method; we need to launch it into its own cog using cognew.  The reason I declare the method private is to remind me not to call this like a regular method (if we did the program would stick in the non-breaking loop).

Before we do that, though, we have to define a variable to hold the digital inputs (17 bits) and some stack space for the new cog (stack space is what the interpreter uses for internal variables).  Add two variables to the program:

var

  long  digins                                                  ' auto-updated variable
  long  distack[16]                                             ' stack for scan_digins cog


Finally, we have to start the cog so this line gets added at the top of the program

  cognew(scan_digins, @distack)                                 ' start scanning cog

Note that I set the scan rate to every 5ms in the scan_digins cog.  Why?  Well, I did a timing test (too involved to get into here) and found that it takes about 0.625ms to scan the inputs, so with everything else we can round up and call it 1ms.  5ms, then, gives us some leeway and it pretty fast (200x per second).  Faster scanning (sub 1ms) would require assembly code (PASM).

Have fun!
 


Jon McPhalen
EFX-TEK Hollywood Office

bsnut

April 02, 2012, 03:33:15 AM #4 Last Edit: April 02, 2012, 03:37:53 AM by bsnut
QuoteHave fun!
I will, like a little kid getting free candy in the candy store ;D. But, this kid needs to wait until the HC-8's are on my door step first.
William Stefan
The Basic Stamp Nut

vince

William I just got mine. Now I just have to wait to play with it it looks like so much fun can't wait till I have some time tomorrow

Vince

bsnut

April 24, 2012, 12:49:18 AM #6 Last Edit: April 24, 2012, 01:02:39 AM by bsnut
One thing I can say, is that this is the coolest board that I ever worked with in many years and I'm having a lot of fun with it :)

But, I am having a bit trouble with the new template that you updated using the "autodigins" method with this simple Propeller code for testing one of the inputs with one of the outputs. So what is the problem with my code?

  long  digins                                       ' auto-updated variable
  long  digstack[16]                                  ' stack for scan_digins cog
 

pub main | t

  setup_io                                                ' setup HC-8+ IO pins
  term.start(RX1, TX1, %0000, 115_200)                    ' start terminal
  pause(1)

  term.tx(CLS)
  term.str(string("EFX-TEK HC-8+ Auto Digins Programming Template", CR, CR))

  t := cnt
  repeat
    if (ttl_bit(0) == YES)
      high(CH0)
    else
      low(CH0) 
    waitcnt(t += constant(10 * MS_001))
William Stefan
The Basic Stamp Nut

JonnyMac

Did you start with the advanced template that's on this page?

-- http://www.efx-tek.com/php/smf/index.php?topic=1714.0

I did and the program worked fine.  I've attached a small modification for you to try.

If you didn't start with the advanced template (it seems I wrote a program for you that did this before posting that template) then you may not have the scanning cog running.  In the advanced template you'll see there is a cognew command controlled by the USE_DIGINS constant.  I can't tell because you didn't attach your code, but I suspect it's missing that cognew.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

And just to be safe, be sure to download and program to EEPROM (F11).  If you use F10 and then the controller gets reset it will reboot to the previous EEPROM program.

It's a good feature to be able to download and run in RAM, but you have to be careful with it.
Jon McPhalen
EFX-TEK Hollywood Office

bsnut

April 24, 2012, 03:57:50 PM #9 Last Edit: April 24, 2012, 04:05:40 PM by bsnut
I'm happy to say my code now works and I found my dump typo mistake  :-[ . 
Quote
If you didn't start with the advanced template (it seems I wrote a program for you that did this before posting that template) then you may not have the scanning cog running.  In the advanced template you'll see there is a cognew command controlled by the USE_DIGINS constant.  I can't tell because you didn't attach your code, but I suspect it's missing that cognew.
Kind of. What I did was, I cut and pasted in the code from the new the advanced template (which is last to be posted) into the old one that was posted. What I didn't do, was check my work and check between the differences in the two programs 

So, here's my code that shows my mistake that I made, with the commented out code was causing my problem that I had.

pub setup_io

'' Configure Propeller IO pins for HC-8+ pcb
'' -- default setup

  high(OUT_EN)                                                  ' disable
  outa[CH7..CH0] := IS_OFF                                      ' set outputs
  dira[CH7..CH0] := IS_ON                                 
  low(OUT_EN)                                                   ' enable

'  high(LD_165)                                                  ' setuip x165 io pins
'  low(CLK_165)
'  input(DO_165)
 
  set_rs485(NOCON)                                              ' RS-485 off
         
  ' launch input scanner ONLY if using TTL or DMX address inputs
 
  if (USE_DIGINS == YES)                                        ' use digital inputs
    cognew(scan_digins, @digstack)                              '  yes, launch scanner
         

QuoteIt's a good feature to be able to download and run in RAM, but you have to be careful with it.
What do mean by being careful with downloading the program into RAM? That's how tested the other programs that you posted. 
William Stefan
The Basic Stamp Nut

JonnyMac

I often use serial output and don't want to add a bunch of stuff at the beginning of my program that holds until the serial program is open.  What I do, then, is download with F11 (to RAM and EEPROM), open the terminal (F12) and then reset the board.  If I did this process using F10 to download the program then the reboot would bring up whatever was last loaded into the EEPROM.

When I'm not using terminal stuff I tend to use F10 as it saves a lot of time.
Jon McPhalen
EFX-TEK Hollywood Office