Analog clock demo using stepper motor. It\'s a demo of simultaneous 3 stepper motor operation. It gets time information from NTP server.
Dependencies: mbed NetEthApiLPC1768 NetServicesLPC1768
main.cpp@0:9bf213f7b780, 2010-11-25 (annotated)
- Committer:
- okano
- Date:
- Thu Nov 25 11:22:43 2010 +0000
- Revision:
- 0:9bf213f7b780
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okano | 0:9bf213f7b780 | 1 | /** Clock demo with stepper motor + NTP |
okano | 0:9bf213f7b780 | 2 | * |
okano | 0:9bf213f7b780 | 3 | * Simple mbed analog clock demo with stepper motor. |
okano | 0:9bf213f7b780 | 4 | * Time information will be get from NTP |
okano | 0:9bf213f7b780 | 5 | * This code based on |
okano | 0:9bf213f7b780 | 6 | * http://mbed.org/users/nucho/programs/SimpleLCDClock/5zi4y |
okano | 0:9bf213f7b780 | 7 | * http://mbed.org/users/okano/notebook/nxp_pcf2127a-demo-code/ |
okano | 0:9bf213f7b780 | 8 | * |
okano | 0:9bf213f7b780 | 9 | * 2010-Nov-20 @tedd_okano |
okano | 0:9bf213f7b780 | 10 | * Released under the MIT License: http://mbed.org/license/mit |
okano | 0:9bf213f7b780 | 11 | */ |
okano | 0:9bf213f7b780 | 12 | |
okano | 0:9bf213f7b780 | 13 | #include "mbed.h" |
okano | 0:9bf213f7b780 | 14 | #include "EthernetNetIf.h" |
okano | 0:9bf213f7b780 | 15 | #include "NtpClient.h" |
okano | 0:9bf213f7b780 | 16 | #include "TextLCD.h" |
okano | 0:9bf213f7b780 | 17 | #include "StepperMotor.h" |
okano | 0:9bf213f7b780 | 18 | |
okano | 0:9bf213f7b780 | 19 | |
okano | 0:9bf213f7b780 | 20 | EthernetNetIf eth; |
okano | 0:9bf213f7b780 | 21 | NtpClient ntp; |
okano | 0:9bf213f7b780 | 22 | TextLCD lcd( p14, p15, p16, p17, p18, p19 ); // rs, rw, d0, d1, d2, d3 |
okano | 0:9bf213f7b780 | 23 | Ticker updater; |
okano | 0:9bf213f7b780 | 24 | StepperMotor m_s( p21, p22, p23, p30 ); |
okano | 0:9bf213f7b780 | 25 | StepperMotor m_m( p24, p25, p26, p30 ); |
okano | 0:9bf213f7b780 | 26 | StepperMotor m_h( p27, p28, p29, p30 ); |
okano | 0:9bf213f7b780 | 27 | AnalogIn ain( p20 ); |
okano | 0:9bf213f7b780 | 28 | |
okano | 0:9bf213f7b780 | 29 | int tz_index = 4; |
okano | 0:9bf213f7b780 | 30 | int update_stop_lcd = false; |
okano | 0:9bf213f7b780 | 31 | int update_stop_hands = false; |
okano | 0:9bf213f7b780 | 32 | int resync = false; |
okano | 0:9bf213f7b780 | 33 | |
okano | 0:9bf213f7b780 | 34 | #define RESYNC_INTERVAL 1 // minutes |
okano | 0:9bf213f7b780 | 35 | |
okano | 0:9bf213f7b780 | 36 | typedef struct _tz { |
okano | 0:9bf213f7b780 | 37 | char *name; |
okano | 0:9bf213f7b780 | 38 | float offset; |
okano | 0:9bf213f7b780 | 39 | } |
okano | 0:9bf213f7b780 | 40 | tz; |
okano | 0:9bf213f7b780 | 41 | |
okano | 0:9bf213f7b780 | 42 | // http://wwp.greenwichmeantime.com/info/timezone.htm |
okano | 0:9bf213f7b780 | 43 | |
okano | 0:9bf213f7b780 | 44 | tz timezone[ 8 ] = { |
okano | 0:9bf213f7b780 | 45 | { "London", 0 }, |
okano | 0:9bf213f7b780 | 46 | { "Amsterdam", 1 }, |
okano | 0:9bf213f7b780 | 47 | { "India", 5.5 }, |
okano | 0:9bf213f7b780 | 48 | { "Singapore", 8 }, |
okano | 0:9bf213f7b780 | 49 | { "Tokyo", 9 }, |
okano | 0:9bf213f7b780 | 50 | { "Hawaii", -10 }, |
okano | 0:9bf213f7b780 | 51 | { "San Francisco", -8 }, |
okano | 0:9bf213f7b780 | 52 | { "New York", -5 }, |
okano | 0:9bf213f7b780 | 53 | }; |
okano | 0:9bf213f7b780 | 54 | |
okano | 0:9bf213f7b780 | 55 | void clock_update( void ); |
okano | 0:9bf213f7b780 | 56 | void show_clock( int h, int m, int s ); |
okano | 0:9bf213f7b780 | 57 | int access_NTP( void ); |
okano | 0:9bf213f7b780 | 58 | |
okano | 0:9bf213f7b780 | 59 | int main() { |
okano | 0:9bf213f7b780 | 60 | m_h.go_angle( 180 ); |
okano | 0:9bf213f7b780 | 61 | m_m.go_angle( 180 ); |
okano | 0:9bf213f7b780 | 62 | m_s.go_angle( 180 ); |
okano | 0:9bf213f7b780 | 63 | |
okano | 0:9bf213f7b780 | 64 | lcd.cls(); |
okano | 0:9bf213f7b780 | 65 | lcd.printf( "Ethernet setting" ); |
okano | 0:9bf213f7b780 | 66 | |
okano | 0:9bf213f7b780 | 67 | EthernetErr ethErr = eth.setup(); |
okano | 0:9bf213f7b780 | 68 | |
okano | 0:9bf213f7b780 | 69 | if (ethErr) { |
okano | 0:9bf213f7b780 | 70 | lcd.printf("Error %d in setup.\n", ethErr); |
okano | 0:9bf213f7b780 | 71 | return -1; |
okano | 0:9bf213f7b780 | 72 | } |
okano | 0:9bf213f7b780 | 73 | |
okano | 0:9bf213f7b780 | 74 | if ( access_NTP() ) { |
okano | 0:9bf213f7b780 | 75 | m_h.go_angle( 0 ); |
okano | 0:9bf213f7b780 | 76 | m_m.go_angle( 0 ); |
okano | 0:9bf213f7b780 | 77 | m_s.go_angle( 0 ); |
okano | 0:9bf213f7b780 | 78 | |
okano | 0:9bf213f7b780 | 79 | return -1; |
okano | 0:9bf213f7b780 | 80 | } |
okano | 0:9bf213f7b780 | 81 | |
okano | 0:9bf213f7b780 | 82 | while ( m_h.distance() | m_m.distance() | m_s.distance() ) |
okano | 0:9bf213f7b780 | 83 | wait( 0.1 ); |
okano | 0:9bf213f7b780 | 84 | |
okano | 0:9bf213f7b780 | 85 | m_h.set_home_position(); |
okano | 0:9bf213f7b780 | 86 | m_m.set_home_position(); |
okano | 0:9bf213f7b780 | 87 | m_s.set_home_position(); |
okano | 0:9bf213f7b780 | 88 | |
okano | 0:9bf213f7b780 | 89 | lcd.cls(); |
okano | 0:9bf213f7b780 | 90 | |
okano | 0:9bf213f7b780 | 91 | updater.attach(&clock_update, 1.0); |
okano | 0:9bf213f7b780 | 92 | |
okano | 0:9bf213f7b780 | 93 | int tz_i = 0; |
okano | 0:9bf213f7b780 | 94 | int tz_i_p = -1; |
okano | 0:9bf213f7b780 | 95 | int unstable = 50; |
okano | 0:9bf213f7b780 | 96 | |
okano | 0:9bf213f7b780 | 97 | while (1) { |
okano | 0:9bf213f7b780 | 98 | |
okano | 0:9bf213f7b780 | 99 | if ( resync ) { |
okano | 0:9bf213f7b780 | 100 | update_stop_hands = true; |
okano | 0:9bf213f7b780 | 101 | |
okano | 0:9bf213f7b780 | 102 | m_h.go_angle( 0 ); |
okano | 0:9bf213f7b780 | 103 | m_m.go_angle( 0 ); |
okano | 0:9bf213f7b780 | 104 | m_s.go_angle( 0 ); |
okano | 0:9bf213f7b780 | 105 | |
okano | 0:9bf213f7b780 | 106 | if ( access_NTP() ) { |
okano | 0:9bf213f7b780 | 107 | return -1; |
okano | 0:9bf213f7b780 | 108 | } |
okano | 0:9bf213f7b780 | 109 | |
okano | 0:9bf213f7b780 | 110 | update_stop_hands = false; |
okano | 0:9bf213f7b780 | 111 | resync = false; |
okano | 0:9bf213f7b780 | 112 | tz_i_p = -1; |
okano | 0:9bf213f7b780 | 113 | } |
okano | 0:9bf213f7b780 | 114 | tz_i = (int)( ain * 7.99 ); |
okano | 0:9bf213f7b780 | 115 | |
okano | 0:9bf213f7b780 | 116 | if ( tz_i != tz_i_p ) { |
okano | 0:9bf213f7b780 | 117 | update_stop_lcd = true; |
okano | 0:9bf213f7b780 | 118 | lcd.locate( 0, 1 ); |
okano | 0:9bf213f7b780 | 119 | lcd.printf( " " ); |
okano | 0:9bf213f7b780 | 120 | lcd.locate( 0, 1 ); |
okano | 0:9bf213f7b780 | 121 | lcd.printf( "%s", timezone[ tz_i ].name ); |
okano | 0:9bf213f7b780 | 122 | update_stop_lcd = false; |
okano | 0:9bf213f7b780 | 123 | |
okano | 0:9bf213f7b780 | 124 | tz_i_p = tz_i; |
okano | 0:9bf213f7b780 | 125 | unstable = 50; |
okano | 0:9bf213f7b780 | 126 | } else { |
okano | 0:9bf213f7b780 | 127 | unstable = unstable ? unstable-- : 0; |
okano | 0:9bf213f7b780 | 128 | tz_index = unstable ? tz_i : tz_index; |
okano | 0:9bf213f7b780 | 129 | } |
okano | 0:9bf213f7b780 | 130 | wait( 0.1 ); |
okano | 0:9bf213f7b780 | 131 | } |
okano | 0:9bf213f7b780 | 132 | } |
okano | 0:9bf213f7b780 | 133 | |
okano | 0:9bf213f7b780 | 134 | void clock_update( void ) { |
okano | 0:9bf213f7b780 | 135 | struct tm dt, *dtp; |
okano | 0:9bf213f7b780 | 136 | time_t t; |
okano | 0:9bf213f7b780 | 137 | char s[ 30 ]; |
okano | 0:9bf213f7b780 | 138 | dtp = &dt; |
okano | 0:9bf213f7b780 | 139 | |
okano | 0:9bf213f7b780 | 140 | t = time( NULL ) + (int)(timezone[ tz_index ].offset * 3600.0); |
okano | 0:9bf213f7b780 | 141 | dtp = localtime( &t ); |
okano | 0:9bf213f7b780 | 142 | |
okano | 0:9bf213f7b780 | 143 | if ( !(dtp->tm_min % RESYNC_INTERVAL) && !(dtp->tm_sec) ) |
okano | 0:9bf213f7b780 | 144 | resync = true; |
okano | 0:9bf213f7b780 | 145 | |
okano | 0:9bf213f7b780 | 146 | if ( !update_stop_hands ) |
okano | 0:9bf213f7b780 | 147 | show_clock( dtp->tm_hour, dtp->tm_min, dtp->tm_sec ); |
okano | 0:9bf213f7b780 | 148 | |
okano | 0:9bf213f7b780 | 149 | if ( update_stop_lcd ) |
okano | 0:9bf213f7b780 | 150 | return; |
okano | 0:9bf213f7b780 | 151 | |
okano | 0:9bf213f7b780 | 152 | strftime( s, 20, "%H:%M:%S", dtp ); |
okano | 0:9bf213f7b780 | 153 | lcd.locate( 0, 0 ); |
okano | 0:9bf213f7b780 | 154 | lcd.printf( "%s", s ); |
okano | 0:9bf213f7b780 | 155 | |
okano | 0:9bf213f7b780 | 156 | #if 0 |
okano | 0:9bf213f7b780 | 157 | strftime( s, 20, "%Y/%b/%d(%a)", dtp ); |
okano | 0:9bf213f7b780 | 158 | lcd.locate( 0, 1 ); |
okano | 0:9bf213f7b780 | 159 | lcd.printf( "%s", s ); |
okano | 0:9bf213f7b780 | 160 | #endif |
okano | 0:9bf213f7b780 | 161 | } |
okano | 0:9bf213f7b780 | 162 | |
okano | 0:9bf213f7b780 | 163 | void show_clock( int h, int m, int s ) { |
okano | 0:9bf213f7b780 | 164 | printf( "%02d:%02d:%02d\r\n",h,m,s ); |
okano | 0:9bf213f7b780 | 165 | |
okano | 0:9bf213f7b780 | 166 | h = h % 12; |
okano | 0:9bf213f7b780 | 167 | m_s.go_angle( -((float)s * 360.0) / 60.0 ); |
okano | 0:9bf213f7b780 | 168 | m_m.go_angle( -((float)m * 360.0) / 60.0 ); |
okano | 0:9bf213f7b780 | 169 | m_h.go_angle( -(((float)h + ((float)m / 60.0)) * 360.0) / 12.0 ); |
okano | 0:9bf213f7b780 | 170 | } |
okano | 0:9bf213f7b780 | 171 | |
okano | 0:9bf213f7b780 | 172 | int access_NTP( void ) { |
okano | 0:9bf213f7b780 | 173 | lcd.cls(); |
okano | 0:9bf213f7b780 | 174 | lcd.printf( "accessing NTP.. " ); |
okano | 0:9bf213f7b780 | 175 | |
okano | 0:9bf213f7b780 | 176 | lcd.locate( 0, 0 ); |
okano | 0:9bf213f7b780 | 177 | lcd.printf("Setup OK"); |
okano | 0:9bf213f7b780 | 178 | |
okano | 0:9bf213f7b780 | 179 | lcd.printf("Timer setting...\n"); |
okano | 0:9bf213f7b780 | 180 | Host server(IpAddr(), 123, "ntp.jst.mfeed.ad.jp"); |
okano | 0:9bf213f7b780 | 181 | ntp.setTime(server); |
okano | 0:9bf213f7b780 | 182 | |
okano | 0:9bf213f7b780 | 183 | lcd.cls(); |
okano | 0:9bf213f7b780 | 184 | |
okano | 0:9bf213f7b780 | 185 | return 0; |
okano | 0:9bf213f7b780 | 186 | } |
okano | 0:9bf213f7b780 | 187 |