First release
Dependencies: EthernetInterface HTTPServer TextLCD mbed-rpc mbed-rtos mbed
main.cpp
00001 /* 00002 * Copyright (c) 2014, Sumio Morioka 00003 * All rights reserved. 00004 * 00005 * This source code was originally written by Dr.Sumio Morioka for use in the Oct 2014 issue of 00006 * "the Interface magazine", published by CQ publishing Co.Ltd in Japan (http://www.cqpub.co.jp). 00007 * The author has no responsibility on any results caused by using this code. 00008 * 00009 * - Distribution date of this code: Aug 26, 2014 00010 * - Author: Dr.Sumio Morioka (http://www002.upp.so-net.ne.jp/morioka) 00011 * 00012 * 00013 * IMPORTANT NOTICE: 00014 * Redistribution and use in source and binary forms, with or without 00015 * modification, are permitted provided that the following conditions are met: 00016 * * Redistributions of source code must retain the above copyright 00017 * notice, this list of conditions and the following disclaimer. 00018 * * Redistributions in binary form must reproduce the above copyright 00019 * notice, this list of conditions and the following disclaimer in the 00020 * documentation and/or other materials provided with the distribution. 00021 * * Neither the name of the copyright holder nor the 00022 * names of its contributors may be used to endorse or promote products 00023 * derived from this software without specific prior written permission. 00024 * 00025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00026 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00027 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00028 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 00029 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00030 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00031 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00032 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00033 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00034 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 */ 00036 00037 #include "mbed.h" 00038 #include "mbed_rpc.h" 00039 00040 #include "TextLCD.h" 00041 #include "LocalFileSystem.h" 00042 00043 #include "EthernetInterface.h" 00044 #include "HTTPServer.h" 00045 #include "FsHandler.h" 00046 #include "RpcHandler.h" 00047 00048 #include "ov7670.h" 00049 00050 TextLCD lcd(p24, p26, p27, p28, p29, p30); 00051 00052 00053 //#define USE_RPCOUT 00054 #undef USE_RPCOUT 00055 00056 #ifndef USE_RPCOUT 00057 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); 00058 PwmOut sv0(p21), sv1(p22), sv2(p23); 00059 #else 00060 RpcDigitalOut led1(LED1, "led1"); 00061 RpcDigitalOut led2(LED2, "led2"); 00062 RpcDigitalOut led3(LED3, "led3"); 00063 RpcDigitalOut led4(LED4, "led4"); 00064 00065 RpcPwmOut sv0(p21, "sv0"); 00066 RpcPwmOut sv1(p22, "sv1"); 00067 RpcPwmOut sv2(p23, "sv2"); 00068 #endif 00069 00070 00071 LocalFileSystem local("webfs"); 00072 00073 OV7670 camera( 00074 p9,p10, // SDA,SCL(I2C / SCCB) 00075 p5,p6,p7, // VSYNC,HREF,WEN(FIFO) 00076 p20,p19,p18,p17,p16,p15,p14,p13, // D7-D0 00077 p8,p11,p12); // RRST,OE,RCLK 00078 00079 //Timer tmr; 00080 00081 #define QQVGA 00082 //#define QVGA 00083 //#define VGA34 00084 00085 #ifdef QQVGA 00086 #define SIZEX 160 00087 #define SIZEY 120 00088 #endif 00089 00090 #ifdef QVGA 00091 #define SIZEX 320 00092 #define SIZEY 240 00093 #endif 00094 00095 #ifdef VGA34 00096 #define SIZEX 480 00097 #define SIZEY 360 00098 #endif 00099 00100 00101 //void cam_cap(void); 00102 void cam_cap(Arguments* input, Reply* output); 00103 RPCFunction rpcFunc(&cam_cap, "cam_cap"); 00104 00105 #ifndef USE_RPCOUT 00106 float sv0_rpc; 00107 float sv1_rpc; 00108 float sv2_rpc; 00109 00110 RPCVariable<float> rpc_sv0_val(&sv0_rpc, "sv0"); 00111 RPCVariable<float> rpc_sv1_val(&sv1_rpc, "sv1"); 00112 RPCVariable<float> rpc_sv2_val(&sv2_rpc, "sv2"); 00113 #endif 00114 00115 int cap_flag; 00116 RPCVariable<int> rpc_cap_flag(&cap_flag, "cap_flag"); 00117 00118 00119 int memfree(void) 00120 { 00121 int ret = 1; 00122 while (1) { 00123 char *p = (char *)malloc(ret); 00124 if (p == NULL) 00125 break; 00126 free(p); 00127 ret++; 00128 } 00129 return (ret); 00130 } 00131 00132 00133 float deg_to_pulsewidth(float deg) 00134 { 00135 // limit range 00136 if (deg < -90.0f) 00137 deg = -90.0f; 00138 else if (deg > 90.0f) 00139 deg = 90.0f; 00140 00141 // return result 00142 return (0.00145f + 0.001f * (deg / 90.0f)); 00143 } 00144 00145 int main() 00146 { 00147 float sv0_val, sv1_val, sv2_val; 00148 00149 #ifndef USE_RPCOUT 00150 led1 = 0; 00151 led2 = 0; 00152 led3 = 0; 00153 led4 = 0; 00154 #else 00155 led1.write(0); 00156 led2.write(0); 00157 led3.write(0); 00158 led4.write(0); 00159 #endif 00160 00161 #ifdef USE_RPCOUT 00162 sv0_val = 0.00045f; // unit: sec 00163 sv1_val = 0.00145f; // unit: sec 00164 sv2_val = 0.00245f; // unit: sec 00165 00166 sv0.period(0.02f); // unit: sec 00167 sv0.pulsewidth(sv0_val); 00168 00169 sv1.period(0.02f); // unit: sec 00170 sv1.pulsewidth(sv1_val); 00171 00172 sv2.period(0.02f); // unit: sec 00173 sv2.pulsewidth(sv2_val); 00174 00175 #else 00176 sv0_val = 0.0f; // unit: deg 00177 sv1_val = 0.0f; // unit: deg 00178 sv2_val = 0.0f; // unit: deg 00179 00180 sv0.period(0.02f); // unit: sec 00181 sv0.pulsewidth(deg_to_pulsewidth(sv0_val)); 00182 00183 sv1.period(0.02f); // unit: sec 00184 sv1.pulsewidth(deg_to_pulsewidth(sv1_val)); 00185 00186 sv2.period(0.02f); // unit: sec 00187 sv2.pulsewidth(deg_to_pulsewidth(sv2_val)); 00188 00189 sv0_rpc = sv0_val; 00190 sv1_rpc = sv1_val; 00191 sv2_rpc = sv2_val; 00192 #endif 00193 00194 cap_flag = 0; 00195 00196 //////////////////////////////////////////////////////////////////////////// 00197 camera.WriteReg(0x12, 0x80); // com7; reset 00198 wait_ms(200); 00199 00200 camera.InitDefaultReg(); 00201 00202 // negate vsync 00203 camera.WriteReg(0x15, 0x02); // com10; negative vsync 00204 00205 #ifdef QQVGA 00206 camera.InitQQVGA(); 00207 #endif 00208 #ifdef QVGA 00209 camera.InitQVGA(); 00210 #endif 00211 #ifdef VGA34 00212 camera.InitVGA_3_4(); 00213 #endif 00214 00215 // data format 00216 camera.WriteReg(0x12, 0x04 + 0); // com7 RGB (bit1...test pattern) 00217 camera.WriteReg(0x40, 0xD0); // com15 RGB565 00218 camera.WriteReg(0x8c, 0x00); // RGB444 00219 00220 wait_ms(300); 00221 00222 //{ 00223 //FILE *f = fopen("/webfs/REG.TXT", "wt"); 00224 //for (int i = 0; i < 256; i++) { 00225 // int val = camera.ReadReg(i); 00226 // fprintf(f, "%02X ", val); 00227 // if ((i % 16) == 15) 00228 // fprintf(f, "\n"); 00229 //} 00230 //fclose(f); 00231 //} 00232 00233 ////////////////////////////////////////////////// 00234 00235 // network 00236 EthernetInterface eth; // locate here 00237 00238 // //Static IP 00239 // char *ip = "192.168.0.20"; 00240 // char *mask = "255.255.255.0"; 00241 // char *gateway = "192.168.0.1"; 00242 // eth.init(ip, mask, gateway); 00243 //DHCP 00244 eth.init(); 00245 00246 eth.connect(); 00247 00248 lcd.locate(0, 0); 00249 lcd.printf("IP %s", eth.getIPAddress()); 00250 00251 // rcp 00252 #ifdef USE_RPCOUT 00253 // RPC::add_rpc_class<RpcDigitalIn>(); // read 00254 RPC::add_rpc_class<RpcDigitalOut>(); // read,write 00255 // RPC::add_rpc_class<RpcDigitalInOut>(); // read,write,input,output 00256 RPC::add_rpc_class<RpcPwmOut>(); // read,write,period,period_ms,pulsewidth,pulsewidth_ms 00257 // RPC::add_rpc_class<RpcAnalogIn>(); // read,read_u16 00258 // RPC::add_rpc_class<RpcAnalogOut>(); // read,write,write_u16 00259 // RPC::add_rpc_class<RpcSPI>(); // format,frequency,write 00260 // RPC::add_rpc_class<RpcSerial>(); // baud,readable,writeable(SPELL?),putc,getc,puts 00261 // RPC::add_rpc_class<RpcTimer>(); // start,stop,reset,read,read_ms,read_us 00262 #endif 00263 00264 // http 00265 HTTPServer svr; // locate here 00266 HTTPFsRequestHandler::mount("/webfs/", "/"); 00267 svr.addHandler<HTTPFsRequestHandler>("/"); 00268 svr.addHandler<HTTPRpcRequestHandler>("/rpc"); 00269 00270 svr.start(80, ð); 00271 00272 // lcd.locate(0, 1); 00273 // lcd.printf("mem %d", memfree()); 00274 00275 #ifndef USE_RPCOUT 00276 led1 = 1; 00277 #else 00278 led1.write(1); 00279 #endif 00280 00281 while (1) { 00282 svr.poll(); 00283 00284 #ifndef USE_RPCOUT 00285 if (sv0_val != sv0_rpc) { 00286 sv0_val = sv0_rpc; 00287 // limit 00288 if (sv0_val < -90.0f) 00289 sv0_val = -90.0f; 00290 else if (sv0_val > 90.0f) 00291 sv0_val = 90.0f; 00292 00293 sv0_rpc = sv0_val; 00294 sv0.pulsewidth(deg_to_pulsewidth(sv0_val)); 00295 00296 lcd.locate(0, 1); 00297 lcd.printf("0:%f ", sv0_val); 00298 } 00299 00300 if (sv1_val != sv1_rpc) { 00301 sv1_val = sv1_rpc; 00302 // limit 00303 if (sv1_val < -90.0f) 00304 sv1_val = -90.0f; 00305 else if (sv1_val > 90.0f) 00306 sv1_val = 90.0f; 00307 00308 sv1_rpc = sv1_val; 00309 sv1.pulsewidth(deg_to_pulsewidth(sv1_val)); 00310 00311 lcd.locate(0, 1); 00312 lcd.printf("1:%f ", sv1_val); 00313 } 00314 00315 if (sv2_val != sv2_rpc) { 00316 sv2_val = sv2_rpc; 00317 // limit 00318 if (sv2_val < -90.0f) 00319 sv2_val = -90.0f; 00320 else if (sv2_val > 90.0f) 00321 sv2_val = 90.0f; 00322 00323 sv2_rpc = sv2_val; 00324 sv2.pulsewidth(deg_to_pulsewidth(sv2_val)); 00325 00326 lcd.locate(0, 1); 00327 lcd.printf("2:%f ", sv2_val); 00328 } 00329 #endif 00330 00331 wait_ms(10); 00332 } 00333 } 00334 00335 00336 //void cam_capture(char *input, char *output) // compile error 00337 void cam_cap(Arguments* input, Reply* output) 00338 //void cam_cap(void) 00339 { 00340 FILE *fp_bmp; 00341 unsigned int d1, d2; 00342 unsigned char sort[3]; 00343 00344 #ifndef USE_RPCOUT 00345 led2 = 1; 00346 #else 00347 led2.write(1); 00348 #endif 00349 00350 cap_flag = 0; 00351 00352 fp_bmp = fopen("/webfs/cam.bmp", "wb"); 00353 00354 ///////////////////////// 00355 // file header 00356 ///////////////////////// 00357 fprintf(fp_bmp, "BM"); 00358 int val = 14 + 40 + SIZEX * SIZEY * 3; // file size 00359 fprintf(fp_bmp, "%c%c%c%c", val % 0x100, val / 0x100, val / 0x10000, val / 0x1000000); 00360 fprintf(fp_bmp, "%c%c%c%c%c%c%c%c", 0, 0, 0, 0, 0x36, 0, 0, 0); 00361 00362 ///////////////////////// 00363 // information header 00364 ///////////////////////// 00365 fprintf(fp_bmp, "%c%c%c%c", 0x28, 0, 0, 0); // header size 00366 fprintf(fp_bmp, "%c%c%c%c", SIZEX % 0x100, SIZEX / 0x100, SIZEX / 0x10000, SIZEX / 0x1000000); 00367 fprintf(fp_bmp, "%c%c%c%c", SIZEY % 0x100, SIZEY / 0x100, SIZEY / 0x10000, SIZEY / 0x1000000); 00368 fprintf(fp_bmp, "%c%c", 1, 0); // # of plane 00369 fprintf(fp_bmp, "%c%c", 24, 0); // bit count 00370 fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); // compression 00371 val = SIZEX * SIZEY * 3; // data size 00372 fprintf(fp_bmp, "%c%c%c%c", val % 0x100, val / 0x100, val / 0x10000, val / 0x1000000); 00373 fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); 00374 fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); 00375 fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); 00376 fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); 00377 00378 camera.CaptureNext(); // sample start! 00379 00380 while(camera.CaptureDone() == false) 00381 ; 00382 00383 camera.ReadStart(); // reset pointer 00384 00385 #ifndef USE_RPCOUT 00386 led3 = 1; 00387 #else 00388 led3.write(1); 00389 #endif 00390 00391 for (int y = 0;y < SIZEY;y++) { 00392 for (int x = 0;x < SIZEX;x++) { 00393 d1 = camera.ReadOneByte() ; // upper nibble is XXX , lower nibble is B 00394 d2 = camera.ReadOneByte() ; // upper nibble is G , lower nibble is R 00395 00396 // RGB565 00397 sort[0] = ((d1 & 0xF8) >> 3) << 3; // R 00398 sort[1] = ( ((d1 & 0x07) << 3) + ((d2 & 0xE0) >> 5) ) << 2; // G 00399 sort[2] = (d2 & 0x1F) << 3; // B 00400 00401 fprintf(fp_bmp, "%c%c%c", sort[2], sort[1], sort[0]); // B,G,R 00402 } 00403 } 00404 00405 camera.ReadStop(); 00406 fclose(fp_bmp); 00407 00408 #ifndef USE_RPCOUT 00409 led2 = 0; 00410 led3 = 0; 00411 led4 = 0; 00412 #else 00413 led2.write(0); 00414 led3.write(0); 00415 led4.write(0); 00416 #endif 00417 00418 cap_flag = 1; 00419 } 00420 00421 // end of file
Generated on Tue Jul 12 2022 21:22:57 by 1.7.2