pulse machine help needed for physiotherapy

Discussion in 'The Projects Forum' started by ollieoscarsid, Mar 18, 2018.

  1. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    Hi all, new to the site and I need some help on a project for my physiotherapist Brother. Between us we need to create a left/right pulse circuit/machine that will assist some of his patients with walking. A kind of reminder that can be felt in the hands alternately to help move the feet.
    I was thinking of using a couple of vibrating motors/cells from a mobile in a little pouch that could be held in the hands or velcroed to a walking frame etc.
    It would need to be variable in frequency and duration, the little cells are 3v
    I'm a mechanical engineer rather than electronic and I would like to help him out, so i thought i'd post this to see if anyone would be kind enough to suggest the circuitry involved.
    Many thanks, Chris
     
  2. BR-549

    Distinguished Member

    Sep 22, 2013
    3,909
    1,009
    It's hard to imagine your concept clearly. Walking frame? Please describe the functional circumstance more clearly.

    ALL details. Have you a video or picture? Is there always a "walking frame"?
     
  3. Raymond Genovese

    Active Member

    Mar 5, 2016
    957
    530
    I think that you are on the right path with the piezo buzzer disks and there are many source and they are cheap - https://www.adafruit.com/product/1740?gclid=EAIaIQobChMIvuqxmrz22QIVhi-BCh2UsQBzEAQYAiABEgLTbvD_BwE or https://www.mouser.com/ProductDetai...MIvuqxmrz22QIVhi-BCh2UsQBzEAQYBSABEgKevfD_BwE

    Certainly the whole circuit could be assembled on a wrist band of some sort, for example.

    Tell us about the variable frequency and duration - what are the details there? What are the range of values and what determines which is used? Depending on the answer there, a cheap micro might come in handy e.g., a low end PIC like a 10F202 or a PICAXE 08M2 if that would be easier..
     
    Last edited: Mar 18, 2018
  4. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    Thanks, that's helpful. The frequency of the 'vibrations' needs to be adjustable from around 0.5-5 seconds and the duration around a similar time, always in a left/right, or one two pattern.

    The whole idea is to remind a patient to put one foot in front of the other after a stroke or similar where the natural thought process has been interrupted. So they feel a vibration in their left hand which tells them to put left foot fwd etc.
     
  5. Raymond Genovese

    Active Member

    Mar 5, 2016
    957
    530
    Hmmm, just thinking out loud...so you could put an accelerometer (even a simple tilt switch might work) on the legs to detect a left stride for example and that would signal a buzz on the right leg...and then you would start looking for the next left stride.

    Without some feedback to tell when a leg is being used, it might be a challenge to know when to buzz what. Some of that can be done inside the program without feedback - that is, always alternating buzzes, but it could become out of sync and be annoying I suppose.
     
  6. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    I don't have a video, but then I'm not sure its needed really. I just need to operate two mobile phone buzzers alternately and be able to adjust the duration and frequency of the buzz's from around 0.5-5 seconds each. Kind of like a two channel metronome. Thanks
     
  7. BR-549

    Distinguished Member

    Sep 22, 2013
    3,909
    1,009
    So all you want is an adjustable audio beats(left and right), for the patient to walk to?
     
  8. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    Correct :)
    But rather than audio, it needs to operate the little vibrating pads so it can be felt in the hands
     
  9. LesJones

    Well-Known Member

    Jan 8, 2017
    1,396
    332
    Does there need to be a gap between the pulses or will there allways be one buzzer operating..
    Like this.
    Left on. Left off and right comes on. Right off and left comes on. And so on.

    Or
    Left on. Left off. Pause. Right on. Right off. Pause. Left on. And so on.

    Les.
     
  10. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    We think alike:), as this was something that I suggested. Apparently it's not actually needed, it seems that flashing lights are used for rehab indoors, hospitals etc which work well, but obviously you can't head towards flashing lights all the time, particularly when outside.

    It's actually more for those suffering with Parkinson's, where a common problem is 'Freezing' I don't fully understand it, but it's something to do with the brain not telling the legs what to do if the thought process is interrupted. A common situation is walking through a doorway, where the person is concentrating on getting through it and forgets to walk again when on the other side, a simple left right pulse helps this. At lease that's how my Brother explained it.
     
  11. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    The second one, left on, for between 0.5-5 seconds (adjustable), left off, pause for 0.5-5 seconds (adjustable) right on etc.
     
  12. BR-549

    Distinguished Member

    Sep 22, 2013
    3,909
    1,009
    Does the patient have the same sensitivity in both hands?
     
  13. ollieoscarsid

    Thread Starter New Member

    Mar 18, 2018
    7
    0
    I think we have to assume so for the time being, thanks
     
  14. BR-549

    Distinguished Member

    Sep 22, 2013
    3,909
    1,009
    If you try and vibrate handle.....it will take power. If you use miniature buzzers or vibrators....you need connecting wires to patient. Are the handles on the frame isolated?

    A light indicator.....or a speaker that says "right" or "left" doesn't take much power and no connecting leads. A small compartment on frame with battery will suffice.

    Only one eye and one ear is needed.

    If vibration is therapeutically necessary.......you might get some background here.

    https://www.precisionmicrodrives.com/vibration-motors

    Everything will be based on the transducer you choose.
     
  15. -live wire-

    Active Member

    Dec 22, 2017
    800
    70
    Try a microcontroller (arduino is reccomended) with some accelerometer ICs. The ICs are small and you can easily attach them to the leg. Then you would have feedback and can program it to buzz based on leg position.
     
  16. LesJones

    Well-Known Member

    Jan 8, 2017
    1,396
    332
    Here is some code that runs on a PIC16F88 that could be modified to do what you want. As it is it sequences through 4 timed states, the time of each controlled by a potentiometer. You could just use two potentiometers, one for the pulse time and one for the pause time.
    Code (Text):
    1.  
    2. ;Sequencer
    3. ;
    4. ;28/06/16
    5. ; Version 01 now being modified for 4 channels (Renamed to Sequencer_02.asm)
    6. ;
    7.  
    8.  
    9. ; I/O port useage
    10.  
    11. ;   RA0   (Pin 17)   Analog in 0
    12. ;   RA1   (Pin 18)   Analog in 1
    13. ;   RA2   (Pin 1)     Analog in 2
    14. ;   RA3   (Pin 2)     Analog in 3
    15. ;   RA4   (Pin 3)
    16. ;   RA5   (Pin 4)     Vpp for programming
    17. ;   RA6   (Pin 15)  
    18. ;   RA7   (Pin 16)  
    19.  
    20. ;   RB0   (Pin 6)     Channel 0 out
    21. ;   RB1   (Pin 7)     Channel 1 out
    22. ;   RB2   (Pin 8)     Channel 2 out
    23. ;   RB3   (Pin 9)     Channel 3 out
    24. ;   RB4   (Pin 10)
    25. ;   RB5   (Pin 11)
    26. ;   RB6   (Pin 12)   PGC for programming
    27. ;   RB7   (Pin 13)   PGD for programming
    28.  
    29.  
    30.  
    31.  
    32.  
    33.    list P=16F88
    34.    #include p16f88.inc
    35.  
    36. ;Program Configuration Register 1
    37.      __CONFIG  _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF  & _INTRC_IO
    38.  
    39. ;Program Configuration Register 2
    40.      __CONFIG  _CONFIG2, _IESO_OFF & _FCMEN_OFF
    41.  
    42. ; Define variables at memory locations
    43.  
    44. ;*******************************************************************************
    45. ; Constants
    46. ;*******************************************************************************
    47.  
    48.  
    49. RAM_START  equ  0x20
    50.  
    51.  
    52. ; The periods are timed with timer1 which is set to run at the internal clock
    53. ; rate (4 Mhz) of Fosc/4 or 1.0MHz which is equal to a 1 uS period.
    54.  
    55.  
    56. ;*******************************************************************************
    57. ; File Register Variables
    58. ;*******************************************************************************
    59.   cblock  RAM_START
    60.  
    61. Save_STATUS     ;Save during interrupt
    62. Save_W       ;Save during interrupt
    63. Save_PCLATH     ;Save during interrupt
    64. Save_FSR     ;Save during interrupt  
    65.  
    66. param1:   1  ; parameter 1  (Used in delay cycles routine)
    67. param2:   1  ; parameter 2  (Used in delay cycles routine)
    68.  
    69. AD_Delay:   1   ;Delay count to allow AD to sample input
    70.  
    71. CH_Time:   1
    72.  
    73. AD_Channel:   1   ;AD channel number
    74.  
    75.   endc
    76.  
    77.  
    78.  
    79. ; start at memory 0
    80.  
    81.    org   0
    82.    goto   SETUP
    83.    org   4
    84.    goto   INTERRUPT
    85.  
    86.  
    87.  
    88.  
    89. Init:
    90. SETUP:
    91.    clrf   PORTB     ; port B outputs low
    92.    clrf   PORTA     ; port A output low
    93.    bsf     STATUS,RP0   ; select memory bank 1
    94.  
    95. ; set inputs/outputs
    96.    movlw   B'00000111'   ; comparators off
    97.    movwf   CMCON
    98.    movlw   B'11110000'   ; port B 0 to 3 outputs 4 to 7 inputs
    99.    movwf   TRISB     ; port B data direction register
    100.    movlw   B'00111111'   ; outputs (0) and inputs (1)
    101.    movwf   TRISA     ; port A data direction register
    102.    movlw   B'11000000'   ; settings (pullups disabled TMR0/2)
    103.    movwf   OPTION_REG
    104.  
    105. ; analog inputs, A/D  
    106.  
    107.    movlw   B'00001111'   ; AN0 to AN3 are analog inputs
    108.    movwf   ANSEL     ;Bank 1
    109.    movlw   B'01000000'   ; left justified A/D result, VCC as ref
    110.    movwf   ADCON1     ;Bank 1
    111.  
    112.    bcf     STATUS,RP0   ; select memory bank 0
    113.    movlw   B'01000000'   ; Fosc  1/8 for  4MHz system clock  
    114.    movwf   ADCON0     ; Bank 0
    115.    bsf     ADCON0,ADON   ; A/D on
    116.    bsf     STATUS,RP0   ; select memory bank 1
    117.    movlw   B'01101000'   ;  for 4 MHz
    118.    movwf   OSCCON     ; Bank 1
    119.  
    120.  
    121. ; Initialized Timer 1
    122.    bcf     STATUS,RP0   ; select memory bank 0
    123.    MOVLW   B'00110100'   ;Clock source FOSC, 1:8 prescale, Dedicated Timer1 oscillator circuit disabled,
    124.   ;Do not synchronize external clock input, Fosc/4 Timer off
    125.          ;So counter will increment every 8 uS  (4 Mhz clock)
    126.          ; So for overflow after 500 ms (62500 * 8uS ) counter would need to be loaded with 0x0BDC
    127.  
    128.    MOVWF   T1CON     ;With 4 Mhz clock timer will increment every 500 mS
    129.  
    130.  
    131.  
    132. START:
    133.  
    134. Main_Loop:
    135.  
    136. Time_CH0:
    137.    BSF   PORTB,0     ;1 cycle  (Set channel 0 output)
    138.    MOVLW   0x00     ;Select channel 0
    139.    MOVWF   AD_Channel  
    140.    CALL   Read_Analog
    141.    CALL   Channel_Delay
    142.    BCF   PORTB,0     ;1 cycle  (Clear channel 0 output)
    143.  
    144.  
    145. Time_CH1:
    146.    BSF   PORTB,1     ;1 cycle  (Set channel 1 output)
    147.    MOVLW   0x01     ;Select channel 1
    148.    MOVWF   AD_Channel  
    149.    CALL   Read_Analog
    150.    CALL   Channel_Delay
    151.    BCF   PORTB,1     ;1 cycle  (Clear channel 1 output)
    152.  
    153.  
    154. Time_CH2:
    155.    BSF   PORTB,2     ;1 cycle  (Set channel 2 output)
    156.    MOVLW   0x02     ;Select channel 2
    157.    MOVWF   AD_Channel  
    158.    CALL   Read_Analog
    159.    CALL   Channel_Delay
    160.    BCF   PORTB,2     ;1 cycle  (Clear channel 2 output)
    161.  
    162.  
    163. Time_CH3:
    164.    BSF   PORTB,3     ;1 cycle  (Set channel 1 output)
    165.    MOVLW   0x03     ;Select channel 3
    166.    MOVWF   AD_Channel  
    167.    CALL   Read_Analog
    168.    CALL   Channel_Delay
    169.    BCF   PORTB,3     ;1 cycle  (Clear channel 1 output)
    170.  
    171.    GOTO   Main_Loop
    172.  
    173.  
    174.  
    175.  
    176.  
    177.  
    178. ;     -----------------------------------------------------
    179.  
    180. ; Interupt handler  (Interrupts not used.)
    181.  
    182. INTERRUPT:
    183. ;Save various registers
    184.  
    185.    MOVWF Save_W     ;Save W  
    186.    MOVF STATUS, W  
    187.    CLRF STATUS      ;Bank 0 will be selected
    188.    MOVWF   Save_STATUS
    189.    MOVF   PCLATH, W
    190.    MOVWF   Save_PCLATH
    191.    MOVF   FSR, W
    192.    MOVWF   Save_FSR
    193.  
    194.  
    195. ;Restore registers
    196.  
    197.    MOVF   Save_FSR, W
    198.    MOVWF   FSR
    199.    MOVF   Save_PCLATH, W
    200.    MOVWF   PCLATH  
    201.    MOVF   Save_STATUS, W  
    202.    MOVWF    STATUS  ;Restore STATUS  
    203.    SWAPF    Save_W, F  
    204.    SWAPF    Save_W, W  ;Restore W  
    205.    RETFIE
    206.  
    207. ;     -----------------------------------------------------
    208. ;Subroutines
    209.  
    210. Read_Analog:       ;Channel number will be in AD_Channel (Bits 0 - 2)
    211.          ;Result returned in "W"
    212.  
    213.    RLF   AD_Channel   ;Move bits to required position (Bits 5 -3)   ;1 cycle
    214.    RLF   AD_Channel   ;1 cycle
    215.    RLF   AD_Channel   ;1 cycle
    216.    BCF   ADCON0, 3   ;1 cycle
    217.    BCF   ADCON0, 4   ;1 cycle
    218.    BCF   ADCON0, 5   ;1 cycle
    219.    MOVF   AD_Channel, W   ;1 cycle
    220.    IORWF   ADCON0, F   ;Select channel   ;1 cycle
    221.  
    222.    MOVLW   D'40'     ;1 cycle       64 decimal
    223.    MOVWF   AD_Delay   ; acquisition time  1 cycle
    224.  
    225. Dec_AD_delay:             ;loop is 3 cycles long (64 x 3 = 192
    226.    DECFSZ   AD_Delay,f   ;1 cycle  (2 on exit)
    227.    GOTO   Dec_AD_delay   ;2 cycles
    228.    BSF     ADCON0,2     ; GO/DONE bit start conversion
    229. WAIT_AD_Ready:
    230.    BTFSC   ADCON0,2     ; conversion complete when cleared ~11 cycles
    231.    GOTO   WAIT_AD_Ready
    232.    MOVF   ADRESH,w
    233.    RETURN     ;2 cycles
    234.  
    235.  
    236.  
    237. Channel_Delay:
    238.    MOVWF   CH_Time   ;1 cycle
    239.    INCF   CH_Time   ;So that AD value of zero does not give maximum time
    240.  
    241. CH_Loop:
    242.    DECFSZ   CH_Time   ;1 cycle (2 cycles on exit)
    243.    GOTO   CH_Delay
    244.    GOTO   CH_End
    245.  
    246. CH_Delay:     ;This generates one unit of channel delay
    247. ;   CALL   DELAY_100mS   ;100mS * 256 =25.6 seconds
    248. ;   CALL   DELAY_50mS   ;50mS * 256 =12.8 seconds
    249.    CALL   DELAY_20mS   ;20mS * 256 = 5.12 seconds
    250.  
    251.    GOTO   CH_Loop
    252.  
    253. CH_End:
    254.    RETURN     ;2 cycles
    255.  
    256.  
    257.  
    258. Delay:
    259.  
    260. DELAY_100mS:
    261. ; Value for param = (100000 - 14)/8 = 99986/8 = 12498 = 0x30D2
    262.  
    263.    MOVLW   0x30     ;   (1 uS)    (1 cycle)
    264.    MOVWF   param2     ;   (1 uS)    (1 cycle)
    265.    MOVLW   0xD2     ;   (1 uS)    (1 cycle)
    266.    MOVWF   param1     ;   (1 uS)    (1 cycle)
    267.    GOTO   delay_cycles
    268.  
    269. DELAY_50mS:
    270. ; Value for param = (50000 - 14)/8 = 49986/8 = 6248 = 0x1868
    271.  
    272.    MOVLW   0x18     ;   (1 uS)    (1 cycle)
    273.    MOVWF   param2     ;   (1 uS)    (1 cycle)
    274.    MOVLW   0x68     ;   (1 uS)    (1 cycle)
    275.    MOVWF   param1     ;   (1 uS)    (1 cycle)
    276.    GOTO   delay_cycles     ;Not needed as delay_cycles follows on from here.
    277.  
    278. DELAY_20mS:
    279. ; Value for param = (20000 - 14)/8 = 19986/8 = 2498 = 0x09C2
    280.  
    281.    MOVLW   0x09     ;   (1 uS)    (1 cycle)
    282.    MOVWF   param2     ;   (1 uS)    (1 cycle)
    283.    MOVLW   0xC2     ;   (1 uS)    (1 cycle)
    284.    MOVWF   param1     ;   (1 uS)    (1 cycle)
    285. ;   GOTO   delay_cycles     ;Not needed as delay_cycles follows on from here.
    286.  
    287. ;*******************************************************************************
    288. ; Function:  delay_cycles
    289. ; Description: Delay a specified number of instruction cycles including
    290. ;  interrupt cycles.  The function call overhead adds between
    291. ;  13 and 16 cycles of delay on top of the specified value.
    292. ; With 4 Mhz system clock and 1:8 prescale
    293. ;Delay will be  param * 2 uS + (13 * 1uS)  + 0 to 3 uS
    294. ;     = param * 8 uS + (13 to16.0 uS)  (Use 14 uS for calculation.)
    295. ;  So param = No. of (uS-14)/8
    296. ; Parameters:  param1 - least significant byte of 16 bit cycle delay
    297. ;  param2 - most significant byte of 16 bit cycle delay
    298. ; Returns:  None
    299. ;*******************************************************************************
    300. delay_cycles:
    301.   comf  param1,F  ; negate the delay by complementing the     (1 uS)    (1 cycle)
    302.   comf  param2,F  ; low and high bytes         (1 uS)    (1 cycle)
    303.   bcf  T1CON,TMR1ON  ; stop timer 1           (1 uS)    (1 cycle)
    304.   movf  param1,W  ; move the low byte of the delay into     (1 uS)    (1 cycle)
    305.   movwf  TMR1L  ; timer 1           (1 uS)    (1 cycle)
    306.   movf  param2,W  ; move the high byte of the delay into     (1 uS)    (1 cycle)
    307.   movwf  TMR1H  ; timer 1           (1 uS)    (1 cycle)
    308.   bcf  PIR1,TMR1IF  ; clear the timer 1 rollover flag     (1 uS)    (1 cycle)
    309.   bsf  T1CON,TMR1ON  ; turn on timer 1         (1 uS)    (1 cycle)
    310.    
    311. tmr1_check:  
    312.   btfss  PIR1,TMR1IF  ; wait for the timer 1 rollover flag to     1 uS while looping    (2 uS) (2 cycle) on exit
    313.   goto  tmr1_check  ; trigger
    314.   return         ;             (2 uS)   (2 cycle)
    315.  
    316.  
    317.    END
    318.  
    319.  
    It could be modified to run on a more modern PIC if required.

    Les.
     
  17. DickCappels

    Moderator

    Aug 21, 2008
    4,863
    1,470
    Just curious, how many of these devices do you imagine will be built, and do you think that using programmable parts to reduce parts count will be an advantage in your case?
     
  18. 128ITSH

    Member

    Jul 20, 2017
    98
    16
    I think the best option for vibration would be a piezo (like Raymond Genovese advised).
    The reasons are:
    - It is small and flat so you can attach it to the patient's hand without too much complexity, as opposed to vibration motors which will probably require special enclosure in order to attach it to the hand.
    - I guess it takes less power than a motor.
    - It is cheaper than a motor.
    A question to you: Where exactly does the vibrating part should be on the patient's hand? by hand do you mean the fist, or could it be higher on the arm? I'm asking this because it will probably be easier on the arm.
     
  19. wayneh

    Expert

    Sep 9, 2010
    14,691
    5,208
    Just something that might interest you:
     
  20. Alec_t

    AAC Fanatic!

    Sep 17, 2013
    8,606
    1,953
    Here's a suggested circuit to energise two phone vibrators/buzzers alternately.
    Pot 1 controls the overall repetition rate (hence the interval between buzzes).
    Pots 2 and 3 control the buzz durations of respective buzzers.
     
Loading...