This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| en:examples:vision [2012/06/18 15:11] – raivo.sell | en:examples:vision [2026/02/19 11:30] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | < | ||
| + | ====== Machine vision ====== | ||
| + | |||
| + | ===== CMUCam3 camera emulation as CMUCam2 ===== | ||
| + | |||
| + | === Required software and references === | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | - [[http:// | ||
| + | |||
| + | === Introduction === | ||
| + | |||
| + | CMUCam3 firmware does not support simple serial communication. Because this capability existed in the CMUCam2 camera, firmware has been created for CMUCam3 that emulates the previous version. You can use the older CMUcam2GUI interface and the serial command set of the CMUCam2. | ||
| + | |||
| + | === Camera setup === | ||
| + | |||
| + | To emulate the CMUCam2 with a CMUCam3 camera, download and install the flash utility (link 6) and the hex file (link 5). After flashing the hex file, the camera is emulated as CMUCam2 and you can use the GUI intended for the previous version to view images. The CMUCam2 datasheet also provides the serial command set for communication. A longer English description of flashing is in the CMUCam3 user manual (link 1). | ||
| + | |||
| + | === CMUCam2 GUI === | ||
| + | |||
| + | This is a graphical user interface for a computer that lets you view camera images and test other functions. The GUI tutorial is in link 3 and the software in link 4. Note that this is a Java program, so you need a JRE (Java Runtime Environment) to run the jar file. | ||
| + | |||
| + | To use the program, connect the camera directly to the computer COM port if possible, or use a USB-Serial adapter. At startup the program asks for the COM port number where the camera is connected. After that the work area opens. | ||
| + | |||
| + | At the top there is a menu where you can select different functions, such as moving servos. To view the camera image, go to the " | ||
| + | |||
| + | The Camera tab is important because clicking a color in the image shows its code. At the same time, other pixels of the same color are highlighted. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Figure 1. Camera GUI window | ||
| + | |||
| + | In Figure 2 the " | ||
| + | |||
| + | |||
| + | {{: | ||
| + | |||
| + | Figure 2. Color Tracking | ||
| + | |||
| + | When searching for colors with HomeLab, this program is useful for determining the color range to track and testing it in practice. On the HomeLab small display you only have numeric information, | ||
| + | |||
| + | ===== Using the CMUCam3 camera with HomeLab ===== | ||
| + | |||
| + | These examples are intended for using the CMUCam3 camera in emulation mode. This does not require programming the camera itself and lets you focus on simpler applications with HomeLab modules. Communication is done using the command set described in the CMUCam2 manual. | ||
| + | |||
| + | ==== HomeLab software ==== | ||
| + | |||
| + | The HomeLab example code is built as much as possible using the HomeLab library. However, serial reading is interrupt-based for speed. The software is split into multiple files. The general functionality, | ||
| + | |||
| + | In CMUCAM.c, the camera-specific functions are located. Currently it includes color search and data reception. Because there are many commands, it is recommended to extend this file as needed, adding support for new packets, etc. | ||
| + | |||
| + | USART.c is dedicated to handling the serial connection. It includes functions to configure the connection and to exchange data in both directions. When data arrives, CMUPacketHandler in CMUCAM.c is executed. It parses the incoming bytes and builds packets. In this example it handles certain packets and can be extended with support for more. | ||
| + | |||
| + | |||
| + | ==== Color tracking ==== | ||
| + | == Required hardware == | ||
| + | |||
| + | - CMUCam3 | ||
| + | - HomeLab Controller module ATmega2561 | ||
| + | - HomeLab Communication module | ||
| + | - HomeLab User Interface module | ||
| + | |||
| + | == Description == | ||
| + | |||
| + | The program configures the CMU camera to track a specific color. The center coordinates of the rectangle drawn around the color area are displayed on the HomeLab screen. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | Figure 3. Program showing coordinates | ||
| + | |||
| + | == Usage == | ||
| + | |||
| + | Connect the modules. Turn on the camera power switch. | ||
| + | Pressing button S2 starts color tracking with the preset color. The result is shown on the display in the format Mx and My, where Mx and My are the center coordinates of the rectangle drawn around the chosen color area. If the color is not seen, zeros are shown. The program is set to search for orange. | ||
| + | |||
| + | * {{: | ||
| + | |||
| + | ==== Simple terminal ==== | ||
| + | == Required hardware == | ||
| + | |||
| + | - CMUCam3 | ||
| + | - HomeLab Controller module ATmega2561 | ||
| + | - HomeLab Communication module | ||
| + | - HomeLab User Interface module | ||
| + | |||
| + | == Description == | ||
| + | |||
| + | The program displays random CMU-CAM packets on the HomeLab screen. It also lets you initialize the camera, start color tracking, and query firmware version using buttons. | ||
| + | |||
| + | == Usage == | ||
| + | |||
| + | Connect the modules. Turn on the camera power switch. | ||
| + | Press S1 to display the camera firmware version. S2 starts the preset color tracking. S3 resets the camera. | ||
| + | |||
| + | * {{: | ||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // CMU CAM 3 juhtimisega seotud funktsioonid | ||
| + | // 2011 | ||
| + | // Autor: Heiko Pikner | ||
| + | // | ||
| + | |||
| + | #include " | ||
| + | |||
| + | |||
| + | // | ||
| + | // Globaalsed muutujad | ||
| + | // | ||
| + | volatile char str_x[5]; | ||
| + | volatile char str_y[5]; | ||
| + | volatile int8_t packet_received = 0; | ||
| + | int8_t packet_t_typ=0; | ||
| + | int8_t pitcounter =0; | ||
| + | |||
| + | // | ||
| + | // Funktsiooni päised | ||
| + | // | ||
| + | void USART_Transmit(unsigned char); | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // Pakettide tõlgendamine ja andmete töötlemine | ||
| + | // | ||
| + | // | ||
| + | void CMUPacketHandler(unsigned char c) | ||
| + | { | ||
| + | |||
| + | |||
| + | // Paketi tähise järgi T paketi tuvastamine | ||
| + | if(c==0x54) | ||
| + | { | ||
| + | packet_t_typ=1; | ||
| + | |||
| + | } | ||
| + | |||
| + | // Paketist Mx ja My eraldamine. Kumbki võib olla 1-3 kohaline | ||
| + | // number. Numbrid on eraldatud tühikutega. Mx talletatakse str_x massiivi | ||
| + | // ja My str_y massivi. Iga massiivi element on üks number. | ||
| + | if(packet_t_typ ==1) | ||
| + | { | ||
| + | pitcounter++; | ||
| + | |||
| + | |||
| + | if(pitcounter==3) | ||
| + | { | ||
| + | |||
| + | str_x[0]=c; | ||
| + | } | ||
| + | |||
| + | if(pitcounter==4) | ||
| + | { | ||
| + | if(c == 0x20) | ||
| + | { | ||
| + | pitcounter=6; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | |||
| + | str_x[1]=c; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | if(pitcounter == 5) | ||
| + | { | ||
| + | |||
| + | if(c == 0x20) | ||
| + | { | ||
| + | pitcounter=6; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | str_x[2]=c; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | if(pitcounter==7) | ||
| + | { | ||
| + | str_y[0]=c; | ||
| + | |||
| + | } | ||
| + | if((pitcounter==8)&& | ||
| + | { | ||
| + | if(c == 0x20) | ||
| + | { | ||
| + | pitcounter=6; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | str_y[1]=c; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | if((pitcounter==9)&& | ||
| + | { | ||
| + | if(c == 0x20) | ||
| + | { | ||
| + | pitcounter=6; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | |||
| + | str_y[2]=c; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | |||
| + | if(c == 0x0D) | ||
| + | { | ||
| + | packet_t_typ=0; | ||
| + | pitcounter=0; | ||
| + | packet_received = 1; | ||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | void GetVersion(void) | ||
| + | { | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | void ResetCam(void) | ||
| + | { | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // Alusta valitud värvi trakkimist. Saada mask 'OM 0 3' ja seejärel | ||
| + | // 'TC 184 234 4 54 0 41' | ||
| + | // | ||
| + | // | ||
| + | void StartTracking(void) | ||
| + | { | ||
| + | // Sea mask, et kaamera saadaks ainult Mx ja My koordinaadid | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | | ||
| + | |||
| + | //Värvi valimiseks on formaat minRed maxRed minGreen maxGreen minBlue maxBlue | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | |||
| + | |||
| + | |||
| + | USART_Transmit(' | ||
| + | USART_Transmit(' | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | #include " | ||
| + | |||
| + | // | ||
| + | //Muutujad, mis on defineeritud mujal | ||
| + | // | ||
| + | |||
| + | extern volatile int8_t packet_received; | ||
| + | |||
| + | extern volatile char str_x[5]; | ||
| + | extern volatile char str_y[5]; | ||
| + | |||
| + | |||
| + | // | ||
| + | //Nuppude viikude valik | ||
| + | // | ||
| + | pin button1 = PIN(C, 0); | ||
| + | pin button2 = PIN(C, 1); | ||
| + | pin button3 = PIN(C, 2); | ||
| + | |||
| + | |||
| + | // | ||
| + | // Seadista süsteem | ||
| + | // | ||
| + | static inline void init() | ||
| + | { | ||
| + | // Seab nupud töökorda | ||
| + | pin_setup_input_with_pullup(button1); | ||
| + | pin_setup_input_with_pullup(button2); | ||
| + | pin_setup_input_with_pullup(button3); | ||
| + | |||
| + | // LCD ekraani algseadistamine | ||
| + | lcd_gfx_init(); | ||
| + | |||
| + | // Ekraani puhastamine | ||
| + | lcd_gfx_clear(); | ||
| + | |||
| + | // Taustavalgustuse tööle lülitamine | ||
| + | lcd_gfx_backlight(true); | ||
| + | |||
| + | // Programmi nime kuvamine | ||
| + | lcd_gfx_goto_char_xy(3, | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | // Kuva Mx | ||
| + | lcd_gfx_goto_char_xy(0, | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | // Kuva My | ||
| + | lcd_gfx_goto_char_xy(0, | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | |||
| + | DDRE = (1<< | ||
| + | |||
| + | // Seriali seadistamine | ||
| + | UsartInit(); | ||
| + | |||
| + | // Katkestuste lubamine | ||
| + | sei(); | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // | ||
| + | //MAIN | ||
| + | // | ||
| + | // | ||
| + | int main(void) | ||
| + | { | ||
| + | unsigned char new_value1, old_value1 = 0, new_value2, | ||
| + | old_value2 = 0, new_value3, old_value3 = 0; | ||
| + | |||
| + | |||
| + | // Seadista süsteem | ||
| + | init(); | ||
| + | |||
| + | |||
| + | while (1) | ||
| + | { | ||
| + | |||
| + | // Loeb nuppude väärtused | ||
| + | new_value1 = pin_get_debounced_value(button1); | ||
| + | new_value2 = pin_get_debounced_value(button2); | ||
| + | new_value3 = pin_get_debounced_value(button3); | ||
| + | |||
| + | // Nupp S1 alla vajutatud | ||
| + | if((!new_value1) && (old_value1)) | ||
| + | { | ||
| + | |||
| + | // Tee midagi | ||
| + | } | ||
| + | |||
| + | // Nupp S2 alla vajutatud | ||
| + | if((!new_value2) && (old_value2)) | ||
| + | { | ||
| + | // Alusta värvi otsimist | ||
| + | StartTracking(); | ||
| + | |||
| + | } | ||
| + | |||
| + | // Nupp S3 alla vajutatud | ||
| + | if((!new_value3) && (old_value3)) | ||
| + | { | ||
| + | // Tee midagi | ||
| + | |||
| + | } | ||
| + | |||
| + | // Jätab eelmised nupuväärtused meelde | ||
| + | old_value1 = new_value1; | ||
| + | old_value2 = new_value2; | ||
| + | old_value3 = new_value3; | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | // Kui pakett on saabunud, kuvab selle sisu ekraanile | ||
| + | if(packet_received == 1) | ||
| + | { | ||
| + | // Vii kursor algusesse | ||
| + | lcd_gfx_goto_char_xy(6, | ||
| + | |||
| + | // Kuva klobaalsest muutujast pakett ja kuva see | ||
| + | lcd_gfx_write_string((char*) & | ||
| + | |||
| + | // Vii kursor algusesse | ||
| + | lcd_gfx_goto_char_xy(6, | ||
| + | |||
| + | // Kuva klobaalsest muutujast pakett ja kuva see | ||
| + | lcd_gfx_write_string((char*) & | ||
| + | |||
| + | |||
| + | |||
| + | // Kustuta vana pakett, ehk täida see tühikutega | ||
| + | memset((char*) &str_x, 0x20, 4); | ||
| + | memset((char*) &str_y, 0x20, 4); | ||
| + | |||
| + | // Nulli paketi saabumist märkiv lipp | ||
| + | packet_received = 0; | ||
| + | } | ||
| + | |||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||