Need help with get_usb_power() - Script Writing - CHDK Forum

Need help with get_usb_power()

  • 5 Replies
  • 2739 Views
Need help with get_usb_power()
« on: 05 / December / 2008, 08:32:41 »
Advertisements
Could someone explain to me how does the get_usb_power() function work, exactly? I am building an motorized pano head controlled from a chdk (lua) script and this function is giving me a lot of grief.

By turning the AF LED on I can rotate the pano head with a constant speed. I also have a USB 'feedback' in a form of a push switch (normally off) that gets momentarily turned on when it passes over a small barrier. That way, by reading the state of the get_usb_power() I can detect when the camera points to a specified direction.
That's the hardware. My script (heavily simplified) is supposed to work like this:

1. determine the rotation speed
- start the rotation
- the time difference between the first and the second get_usb_power()>0 is the period of one full rotation

2. shoot the photos
- a bunch of math to determine the slide angle from photo to photo
- a loop that slides for the said angle, takes a photo and checks if get_usb_power() got triggered (to know when to stop)

The problem is that the speed is always correctly measured but the same get_usb_power() function does not, most of the time, get triggered (>0) in the photo-taking loop. Let me repeat that. When I have a continuous rotation the 'switch' works but when I loop slide-stop-slide-stop... the switch stops working. Here are both functions:

Code: [Select]
function calibrate()
  local t
  local tt 
  get_usb_power()
  set_led(9,1)
  repeat
    sleep(1)
  until get_usb_power()>0
  t=get_tick_count()
  repeat
    sleep(1)
  until get_usb_power()>0
  set_led(9,0)
  tt=get_tick_count()
  az=0
  return tt-t
end

function slide(time)  -- slide (rotate) for a specified duration
  local t=0
  local p=0
  local tt=0
  get_usb_power()  -- clear
  set_led(9,1)         -- start the rotation
  t=get_tick_count()  -- start time
  repeat
    sleep(1)
    p=get_usb_power()
  until p>0 or get_tick_count()-t>time
  set_led(9,0)            -- stop the rotation
  tt=get_tick_count()  -- end time
  if p>0 then       
    print("full circle")
    return 1
  else
    return nil
  end
end

Does anyone know why would get_usb_power() fail to return positive integer when the power was on and off?
« Last Edit: 05 / December / 2008, 08:35:15 by dsvilko »

*

Offline zeno

  • *****
  • 885
Re: Need help with get_usb_power()
« Reply #1 on: 05 / December / 2008, 09:37:48 »
The way get_usb_power works is that if power is being applied a counter is incremented in the keyboard routines - this counter is stored and reset to 0 when the power is removed. get_usb_power returns the stored value (and also resets the counter).

I can't see anything obviously wrong with your logic, but I note that you are sleeping for just 1 ms in the loop. This would be fine in uBasic (where each line takes 10ms to execute) but perhaps not in Lua - you may not be waiting long enough. Try increasing it to 10 ms and see if that makes any difference.
A570, S100, Ixus 127
Author of ASSIST, STICK, WASP, ACID, SDMInst, LICKS, WICKS, MacBoot, UBDB, CFGEdit

Re: Need help with get_usb_power()
« Reply #2 on: 05 / December / 2008, 09:58:55 »
Thanks for the quick reply!
I have started with the 10ms sleep but reduced it to see if that would solve the problem.
This is really driving me crazy. For some slide durations it always works, for some it never works on the first pass but triggers on the second. It seems that the triggering of get_usb_power() depends on how late or early in the loop (slide function) the switch is activated. Do you see any software reason why this should be so?

*

Offline zeno

  • *****
  • 885
Re: Need help with get_usb_power()
« Reply #3 on: 05 / December / 2008, 12:30:04 »
I don't I'm afraid. But I don't know enough about Lua. Your 'repeat .. until' has this test:
   until p>0 or get_tick_count()-t>time
Are you sure that the priority of the various operators is OK? I would probably have written:
   until (p>0) or ((get_tick_count()-t)>time)
just to make sure!
A570, S100, Ixus 127
Author of ASSIST, STICK, WASP, ACID, SDMInst, LICKS, WICKS, MacBoot, UBDB, CFGEdit


*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Need help with get_usb_power()
« Reply #4 on: 05 / December / 2008, 12:38:38 »
AFAIK, sleep(1) in Lua is equivalent to sleep(9) and sleep(10) and sleeps until next keyboard interval just like in uBASIC. Sleep is one of the few commands that cause this yield, see http://chdk.setepontos.com/index.php/topic,1194.msg22785.html#msg22785 .


I don't know/remember these remote things well, but I was under the impression that USB voltage detection may be more inaccurate than 10 ms at least the old non-synched way. You could probably try slowing things down significantly to make it all make sense, and then see how much you can speed it up when it works in slow motion?

*

Offline Jucifer

  • *****
  • 251
  • [A710IS]
Re: Need help with get_usb_power()
« Reply #5 on: 05 / December / 2008, 14:27:14 »
Just to add a little confusion, there's this:

(core/luascript.c)
Code: [Select]
static int luaCB_get_usb_power( lua_State* L )
{
  if (luaL_optnumber( L, 1, 0 )) lua_pushnumber( L, get_usb_power(1) );
  else lua_pushnumber( L, get_usb_power(0) );
  return 1;
}

and this:

(platform/generic/kbd.c)
Code: [Select]
int get_usb_power(int edge)

{

int x;



if (edge) return remote_key;

x = usb_power;

usb_power = 0;

return x;

}

That is, calling get_usb_power() waits while remote is pressed and returns time after releasing, get_usb_power(1) returns 1 if remote is pressed, 0 if not.

Should get_usb_power() accept also strings?
e.g. get_usb_power(edge/pressed/...) would be more informative...

 

Related Topics