May 04, 2024, 01:40:21 AM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


Use HC-8+ to control servos in a talking head

Started by davisgraveyard, August 14, 2017, 10:33:20 PM

Previous topic - Next topic

davisgraveyard

I checked the code and idle
  •   are intialized as 0.  If I do an extra readln,80 it seems to work?   Not sure why?  Still haven't tested the eye on  timing with show code.  I think all the issues are related with the faster speed of the propeller and the multitasking nature.   

    1.   Servo idle vales set from first  line of text (adjust reading code?)
    2.  LED not fading smoothley (some sort of power level timing?)
    3.  LCD eyes not powering on until servo movement is running  (need to force this to complete before starting servo loop)



davisgraveyard

I found the source of one of my problems.  The power supply.  On my test bench I am using a 1.2A 12VDC PS and a 300Ma 12VDC PS.  the 300MA one is fine for driving the AP-16 but didn't work well for the HC-8+.  WHen I use the 1.2A the LED fades fine.  I must be using something less than 1.2A in my prop? 

Still seeing the issue with the servos not getting set to idle correctly from the first line in the data file.   I'm searching the code and debugging this one.

And the LCD EYE power is going to need a short pause to delay things which I can fix.


davisgraveyard

For those that are following and to Jon.  I worked on the code last night to figure out what is going on with the servo Idle
  • values not getting initialized and the servos getting reset to zero positions.   The show would play without issue every time.  But the concept of opening the file reading the first line out was not.  I'm still not sure what is going on but if I remove the check and just let the player read the file and i check if line = 0 and store the values then the servos idle in position.


      line := 0
     
      t := cnt                                                      ' sync to system timer
      repeat
        check := rd_line(@linebuf, 80)                              ' read line from file
        if (check =< 0)                                             ' if EOF, break out of loop           
          quit                         
        else
          replace(@linebuf, 13, 0)                                  ' strip CR from input line   
          parse_values(@linebuf)                                    ' parse data from it         
          servo.set(NOD,  nodpos , 0)                                                     
          servo.set(TILT, tiltpos, 0)                                                     
          servo.set(TURN, turnpos, 0)
         
          time.mark

          if (line == 0)
            idle[NOD]  := nodpos        ' extract & covert to us
            idle[TILT] := tiltpos
            idle[TURN] := turnpos
     
          if (DEBUG == YES)
            term.rjdec(++line,   4, " ")                            ' show line from file
            term.rjdec(nodpos,   8, " ")
            term.rjdec(tiltpos,  6, " ")
            term.rjdec(turnpos,  6, " ")
            term.rjdec(frtiming, 8, " ")
            term.tx(13)
         
          waitcnt(t += (frtiming * MS_ADJ))                         ' real-time delay (adjusted)               

      t := time.millis                                              ' capture show time
       
      close_file

      set_idle_position




JonnyMac

I've been on a road trip, hence very busy -- and you'll learn more by digging in than having me do everything, anyway.

All the pieces are there. At the beginning of the program, open the file, read the first line, parse those values, then save them as your start positions. Send these to the servo driver at the top of the loop (before the fade-up of the eyes).
Jon McPhalen
EFX-TEK Hollywood Office

davisgraveyard

I am more than comfortable wading through the code and most if not all if it makes sense to me and I am able to make changes as needed in most cases.  Even add debug statements to help figure stuff out and move code around as needed.

But there are some basic concepts that I might not understand when it comes to the cogs in the propeller code or the architecture of the cpu.  How things are executed and how to set priority or pause execution or make things happen synchronously.   I'm a C# .NET guy so I get multithreading and background tasks with callbacks etc.  But I only understand it from a Intel Process and Windows using .NET.

the code at the start of the program is not reading any data out of the file.  No error opening the file but the buffer is empty.  But once the show starts the reads work fine.  The initial file check code happens right after the setup which intializes IO and the SD card reader.  Could that not be complete when the data read happens but is complete by the time the show plays?   I think it is some sort of race condition.  All my debugs show that the file open is valid but the read is a blank line and there is no data to parse.

Similarly it appears that the outs.high(EYES) seems to happen on its on thread independent of the play_show() call?   I placed a time.pause(3_000) after it to make sure it is on before the ap16_wav() or play_show() are called which does help but the timing still  seems to be almost random when it is fully powered on?

                                                     
pub main                                             
                                                                 
  setup                                                         ' setup io and objects
 
  'verify_servo_file(@ServoFile)

  ap16_stop(%00)

  if (DEBUG == YES)
    term.rxflush
    term.rx
    term.tx(term#CLS)
 
  repeat
    if (DEBUG == YES)
      term.tx(term#CLS)
      term.str(string("Starting show.", 13, 13))
 
    fade_spotlight(0, 255, 6000)                                ' #1
    outs.high(EYES)
    time.pause(6_000)                                           ' #2
    ap16_wav(%00, @AudioFile, 1)                                ' #3
    play_show(@ServoFile)                                       ' #4

    ' optional
    ' -- must use 2400 baud with G command on older AP-16s
    {
    repeat while (ap16_playing(%00))                            ' #5
      time.pause(20)
    }
       
    outs.low(EYES)                                              ' #6
    fade_spotlight(255, 0, 6000)                                ' #7
    time.pause(120_000)                                         ' #8