Programming Joypad with Arduino Uno R3 and HC05 (Old version)

 

 



It is a wifi remote controller built with arduino uno and HC05 wifi module. It is powered by 2 pieces of lipo batteries.

Construction

Pin Assignment

Pin Function remarks
PB0 key drive SW20, SW30
PB1 key drive SW21, SW31
PB2 key drive SW22, SW32
PB3 LED
PB5 LED UNO
PD0 RX UART
PD1 TX UART
PD2 key sense SW2, SW20, SW21, SW22
PD3 key sense SW3, SW30, SW31, SW32
AREF ADC battery



PB1



^

PB0 < PD2 > PB2


v



GND

Keypad

Circuit

As shown in the diagram, there are four buttons. Each button is connecting to two signals. Red means high and black means low. PD2 is the sensing signal which is weakly pulled high. PB0 to PB3 can be either low or floating. Click the checkboxes to see how PD2 responds.  The other button group is similar, except the sensing pin is changed to PD3.

Data Format


GND











GND
PB2 PD2 PB0

PB0 PD3 PB1

PB1

ASCII

PB2

When a button is pressed or released, this information is sent via UART. Each 4-button group needs 3 bits to represent its state. So one byte is enough. Data shall be sent only when change occurs.

Coding


/* main.c */
e u   e    a e   O   O     O  A    A      O  };
 oi  i i   oi  ;              i i ia i e  o    i     i e   ua   a   a  
 oi   ai     u  i  e  i   ;
 oi   e  e u   e    a e ;
i    a  e    o   oi     a  e    u    oi  ;
 oi    u  o    oi  ;          a   ea     u   o   ua  

i    ai     
    i i   ;
     e  O  ;                  i  i a e  a  e ie  a e  o  e  e 
     ai          ;
      i e    a  e    o      e   a  e    u       O     A   ;
     e  O   ;
      u  o    ;                o  e u e   o   a  e  a  e ie 
      i e   ;
}
 n m l d_st t  {  N,  FF, N RM L, F ST, SL W } 
v  d  n t(v  d)             // n t  l z  p rt p ns, t m r,   rt  nd  dc
v  d w  t_ms( ns gn d  nt) 
v  d l d( n m l d_st t ) 
 nt b tt ry_l w(v  d), b tt ry_f ll(v  d) 
v  d sh td wn(v  d)         // t l  st sh t d wn   rt

 nt m  n() {
     n t() 
    l d( N)                 // nd c t  b tt r  s  r  c nn ct d
    w  t_ms(1000) 
    wh l  (!b tt ry_l w()) l d(b tt ry_f ll() ?  N : F ST) 
    l d( FF) 
    sh td wn()              //f rc   s r t  ch ng  b tt r  s
    wh l (1) 
}

Key scanning shall be running in background.

I need a timer interrupts at 1 milli-second interval, a uart with baud rate 9600, an adc with input connects to the 1.1 volt reference.

Toggle LED at 1 second

It is to verify timer setting and LED.

/* isr.c */
 i   u e  a   i  e  u     

e u   e    a e  O   O     O  A    A      O };
 oi   ai     u  i  e  i       }
 oi   e  e u   e    a e     }
i    a  e    o   oi      e u    ; }
i    a  e    u    oi      e u   1; }
 oi    u  o    oi            = U      =      = A    A =  ; }

 oi  i i   oi    
         =     ;                         5    3 a  ou  u 
         =     ;                         1=  
     O    =     ;                       e   e  e  i    u    i  
         A =  ;                           
    O   A =   9;                       1   
    U     = 1 3;                        au =9   
     I     =  ;                        e a  e  I E    O  A
    A  U  = 1 ;                        A e   1 1 
    A    A =    7;                     A   o     e  a a =1  
           = 3;                          e  a a =     u 
    U      =       E   ;                u   o  ua  
     ei  ;                             e a  e i  e  u  
}

I    I E    O  A  e     
      a i  i    ou  ;
    i      ou     999   
         ou   =  ;
         I   =     3 ;
    }
}
# ncl d  < vr/ nt rr pt.h>

 n m l d_st t  { N,  FF, N RM L, F ST, SL W} 
v  d w  t_ms( ns gn d  nt t) {}
v  d l d( n m l d_st t  s) {}
 nt b tt ry_l w(v  d) { r t rn 0  }
 nt b tt ry_f ll(v  d) { r t rn    }
v  d sh td wn(v  d) { TCCR0B    CSR0B   DDRB    DCSR    0  }

v  d  n t(v  d) {
    DDRB   0x28                      //PB , PB   s   tp t
    DDRD   0x02                      //PD  TX
    P RTD   0x0c                     //k y s ns  p ns p ll h gh
    TCCR0    2                       //CTC
     CR0    24                       //  ms
     BRR0    0                       //b  d  600
    T MSK0   2                       // n bl  T M R0 C MP 
     DM X    4                       // r f,  . V
     DCSR    0x8                     // DC  n, pr sc l r  28
    TCCR0B                           //pr sc l r 64, r n
     CSR0B   _BV(TX N0)              //t rn  n   rt
    s  ()                            // n bl   nt rr pt
}

 SR(T M R0_C MP _v ct) {
    st t c  nt c  nt 
     f (++c  nt >    ) {
        c  nt   0 
        P NB   _BV( ) 
    }
}

Implementation of led()

/* led.c */
 i   u e  a   io   

e u   e    a e   O   O     O  A    A      O  };

  a i  e u   e    a e   a e = O  ;
  a i  i    ou     u a io ;

 oi   e  e u   e    a e     
    i    ;
      a e =  ;
    i     ==  O  A     = 1   ;
    i     ==  A      = 5  ;
    i     ==   O     =     ;
     I      =      O IE A ;
     u a io  =  ;
     I      =     O IE A ;
}

 oi    e   oi    
    i     a e == O      O     =     3 ;  e u  ; }
    i     a e == O       O     =      3 ;  e u  ; }
    i      ou      u a io      ou   =  ;  I   =     3 ; }
}
# ncl d  < vr/  .h>

 n m l d_st t  {  N,  FF, N RM L, F ST, SL W } 

st t c  n m l d_st t  st t     FF 
st t c  nt c  nt, d r t  n 

v  d l d( n m l d_st t  s) {
     nt t 
    st t    s 
     f (s    N RM L) t    000 
     f (s    F ST) t    00 
     f (s    SL W) t   2000 
    T MSK0 &  ~_BV( C  0 ) 
    d r t  n   t 
    T MSK0 |  _BV( C  0 ) 
}

v  d _l d(v  d) {
     f (st t      N) { P RTB |  _BV( )  r t rn  }
     f (st t      FF) { P RTB &  ~_BV( )  r t rn  }
     f (++c  nt > d r t  n) { c  nt   0  P NB   _BV( )  }
}

void _led(void);
ISR(TIMER0_COMPA_vect) {
    _led();
}

Implementation of wait(unsigned int)

/**/
  a i  u  i  e  i    i  ;

u  i  e  i    e  i    oi    
    u  i  e  i    ;
     I      =      O IE A ;
      =  i  ;
     I      =     O IE A ;
     e u    ;
}

 oi   ai     u  i  e  i       
       =  e  i    ;
      i e     =  e  i     ;
}

 oi    e   oi  ;
I    I E    O  A  e     
       i  ;
      e   ;
}
st t c  ns gn d  nt t ck 

 ns gn d  nt g tT ck(v  d) {
     ns gn d  nt t 
    T MSK0 &  ~_BV( C  0 ) 
    t   t ck 
    T MSK0 |  _BV( C  0 ) 
    r t rn t 
}

v  d w  t_ms( ns gn d  nt t) {
    t +  g tT ck() 
    wh l  (t !  g tT ck()) 
}

v  d _l d(v  d) 
 SR(T M R0_C MP _v ct) {
    ++t ck 
    _l d() 
}

Implementation of adc functions

/* adc.c */
 i   u e  a   io   

  a i  i    e u  ;

  a i  i    e  e u    oi    
    i    ;
     I      =      O IE A ;
      =  e u  ;
     I      =     O IE A ;
     e u    ;
}

i    a  e    o   oi      e u    e  e u       51 ; }      7    o   
i    a  e    u    oi      e u    e  e u        9 ; }     7 7  o   

 oi   a    oi    
     e u   = A  ;
    A    A  =     A    ;
}
# ncl d  < vr/  .h>

st t c  nt r s lt 

st t c  nt g tR s lt(v  d) {
     nt r 
    T MSK0 &  ~_BV( C  0 ) 
    r   r s lt 
    T MSK0 |  _BV( C  0 ) 
    r t rn r 
}

 nt b tt ry_l w(v  d) { r t rn g tR s lt() >   0  }   //~ .4 v lts
 nt b tt ry_f ll(v  d) { r t rn g tR s lt() < 4 0  }  //~ .  v lts

v  d _ dc(v  d) {
    r s lt    DC 
     DCSR  |  _BV( DSC) 
}

void _led(void), _adc(void);
ISR(TIMER0_COMPA_vect) {
    ++tick;
    _led();
    _adc();
}

Implementation of keypad scanning

/* key.c */
 i   u e  a   io   

 oi    e   oi    
      a i  i    ou  ;
      a i    a   e ;
      a    =  ;
    i      ou     1    e u  ;
     ou   =  ;
          =       ;
    i      I                 =       ;
    i      I         3       =     3 ;
          =        ;
          =     1 ;
    i      I                 =     1 ;
    i      I         3       =       ;
          =      1 ;
          =       ;
    i      I                 =       ;
    i      I         3       =     5 ;
          =        ;
    i     ==  e    e u  ;
     e  =  ;
    U    =         e ;
}
# ncl d  < vr/  .h>

v  d _k y(v  d) {
    st t c  nt c  nt 
    st t c ch r k y 
    ch r k   0 
     f (++c  nt <  0) r t rn 
    c  nt   0 
    DDRB |  _BV(0) 
     f (!(P ND & _BV(2))) k |  _BV(0) 
     f (!(P ND & _BV( ))) k |  _BV( ) 
    DDRB &  ~_BV(0) 
    DDRB |  _BV( ) 
     f (!(P ND & _BV(2))) k |  _BV( ) 
     f (!(P ND & _BV( ))) k |  _BV(4) 
    DDRB &  ~_BV( ) 
    DDRB |  _BV(2) 
     f (!(P ND & _BV(2))) k |  _BV(2) 
     f (!(P ND & _BV( ))) k |  _BV( ) 
    DDRB &  ~_BV(2) 
     f (k    k y) r t rn 
    k y   k 
     DR0   0x40 | k y 
}

void _led(void), _adc(void), _key(void);
ISR(TIMER0_COMPA_vect) {
    ++tick;
    _led();
    _adc();
    _key();
}

Turn off compiler optimisation. _key() is timing critical.

留言

這個網誌中的熱門文章

EIE3105 / EIE3106 Robot Car Info (2024 Jan - Apr) - Integrated Project

PolyU EIE3105 / EIE3106 (2022-2023) EIE JoyPad & MCU Control PCBs - Important Note (Robot Car) - Integrated Project

PID Speed Control