TeachingWs12IMGeDevice

Chair for Computer Aided Medical Procedures & Augmented Reality
Lehrstuhl für Informatikanwendungen in der Medizin & Augmented Reality

TeachingWs12IMGeDevice

This page collects a number of more technical topics about the IMGe Interaction Device.

If you have any questions, feel free to contact me at huberma@in.tum.de

Picture1.jpg

Protocol summary

The following commands are supported by the latest firmware:

CommandWrite stringReceive stringExampleExercise
Query GPIO"1"32 bit GPIO register as hex string"1" -> "00000120"1
Interrupt driven Button events"2"Event messages "E: x" or "None"; uppercase indicates pressed, lowercase released"2" -> "E: C"2
Extended Button events"3"Button event data with timestamps as 32 bit hex string"3" -> "E: d 0000198B"2
Query Analog ports"4"4 times 16 bit ADC values as hex strings prefixed by "A: ""4" -> "A: 0856 0FFE 0003 0000"3
LED control"l x y\r\n", x is LED number (0 to 3), y is either 0: off, 1: on or 2: toggle"Done.""l 1 2\r\n" -> "Done."4
Motor control"m x\r\n", x is motor power (0 to 1000)"Done.""m 300\r\n" -> "Done."4
Query Accelerometer"a"3 times signed 8 bit accelerometer values as hex strings prefixed with "Accel: ""a" -> "Accel: 04 FE C3"5
Debug: Toggle all outputs"5""Ok""5" -> "Ok"-
Debug: Get firmware version"v"Version ID string"v" -> "IMGe Device Version T6 .9 Hash: 6fb8d918a97c451e900da197ae65777320f6968f"-

Communications via C/C++

Example for doing serial communicaitons in C/C++ on Linux/Mac or Windows

Linux/Mac version:

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h>  
#include <termios.h> 
#include <iostream>
#include <cstring>

char readBuf[8]; char stringBuffer[64];

int main() { int fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY); // On Mac: find correct devices using Terminal ls /dev/tty.*

if(fd == -1) { perror("Unable to open serial port\n"); return (0); }

std::cout << "Serial Port opened\n";

int res = 0; char* recPtr = stringBuffer;

while(1) { // Write to Serial Port (Write the character "4" for ADC values) res = write(fd, "4", 1); if (res != -1) { std::cout << "Write OK" << std::endl; } else { std::cout << "Error writing to serial port" << std::endl; } memset(readBuf, 0x00, 8); memset(stringBuffer, 0x00, 64); recPtr = stringBuffer;

// Read from Serial Port while (1) { res = read(fd,readBuf,1); if (res > 0) { // stop at end of line if (readBuf[0]==0x0d) { // flush rest of available characters while (read(fd,readBuf,1)>0) ; break; } else { *recPtr = readBuf[0]; recPtr++; } } }

std::cout << "Read string: " << stringBuffer << std::endl;

// Write to Serial Port (Write "1" for button register res = write(fd, "1", 1); if (res != -1) { std::cout << "Write OK" << std::endl; } else { std::cout << "Error writing to serial port" << std::endl; }

memset(readBuf, 0x00, 8); memset(stringBuffer, 0x00, 64); recPtr = stringBuffer;

// Read from Serial Port while (1) { res = read(fd,readBuf,1); if (res > 0) { // stop at end of line if (readBuf[0]==0x0d) { // flush rest of available characters while (read(fd,readBuf,1)>0) ; break; } else { *recPtr = readBuf[0]; recPtr++; } } }

std::cout << "Read string: " << stringBuffer << std::endl;

} close(fd); return (0); }

Windows version:

#include "stdafx.h"
#include <iostream>
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[]) { HANDLE hSerial; DWORD bytesTransferred;

hSerial = CreateFileA("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hSerial == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { std::cout << "Port not found" << std::endl; } else { std::cout << "Cannot open port" << std::endl; } } else { std::cout << "Serial port openend" << std::endl; }

// Set timeouts to 0 for non-blocking reading COMMTIMEOUTS timeouts; memset((void *)&timeouts, 0x00, sizeof(timeouts)); timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hSerial, &timeouts);

char readBuffer[8]; char stringBuffer[128]; char* recPtr = stringBuffer;

while(1) { // Write "1" to get the button register if (WriteFile(hSerial, "1", 1, &bytesTransferred, NULL)) { std::cout << "Cannot write to serial port" << std::endl; } else { std::cout << "Write OK" << std::endl; }

memset((void *)readBuffer, 0x00, 8); memset((void *)stringBuffer, 0x00, 128); recPtr = stringBuffer;

while(1) { int res = ReadFile(hSerial, readBuffer, 1, &bytesTransferred, NULL); if (res && bytesTransferred) { if (readBuffer[0] == 0x0d) { while (ReadFile(hSerial, readBuffer, 1, &bytesTransferred, NULL) && bytesTransferred) ; break; } else { *recPtr++ = readBuffer[0]; } } } std::cout << "Read string: " << stringBuffer << std::endl;

// Write "4" to read the ADCs if (WriteFile(hSerial, "4", 1, &bytesTransferred, NULL)) { std::cout << "Cannot write to serial port" << std::endl; } else { std::cout << "Write OK" << std::endl; }

memset((void *)readBuffer, 0x00, 8); memset((void *)stringBuffer, 0x00, 128); recPtr = stringBuffer;

while(1) { int res = ReadFile(hSerial, readBuffer, 1, &bytesTransferred, NULL); if (res && bytesTransferred) { if (readBuffer[0] == 0x0d) { while (ReadFile(hSerial, readBuffer, 1, &bytesTransferred, NULL) && bytesTransferred) ; break; } else { *recPtr++ = readBuffer[0]; } } } std::cout << "Read string: " << stringBuffer << std::endl; }

return 0; }

Hardware

The basis of the interaction device is the STMicroelectronics ARM development board "ST32F4Discovery". You can order one of these for example from RS-Components. Search for "STM32F4DISCOVERY" or order code "745-8434".

The development board is extended by two daughterboards, the IMGE-C-PCB Cover board (no functionality, only cover) and the IMGE-I-PCB Interaction Board.

You can find the files for schematics and the layouts here. The design was done using the open EDA suite Kicad, but also PDFs for schematics and PCB layout layers are included. Furthermore Bills of Materials (bom.txt files) are included, detailing the required components and possible sources (in german only so far, sorry).

IMGE-I-PCB.pngIMGE-C-PCB.png

Firmware

Source

The firmware was compiled using the GCC-Toolchain for ARM targets, such as GNU ARM or YAGARTO for example. You can find the current version of the firmware here: https://github.com/ponymorphism/imge-cactus-firmware . It is in some parts based on the example projects and device libraries from STMicroelectronics.

To compile, enter the "main" subdirectory and just call "make". The resulting image will be called "main.bin" which you can flash on your own devices using the methods detailed below.

Do not try to re-flash devices in the games labs. If you need to change something on these devices, contact us.

Images

  • Here are the firmwares used in the exercises
  • T4.bin: Exercises Tutorial 4 Firmware a2f1b0aa34b5329522aba2491197207dcad975e3
  • T6.bin: Exercises Tutorial 5 Firmware 222e52f54af48bdb10f84520abcb21d1f6a523d0
  • T7.bin; Exercises Tutorial 7 (includes Sound input support)

Flashing your device

  • The STM32F4Discovery board comes with a ST-Link 2 programming interface

  • Linux:
  • Get the st-flash tool by pulling the repository from https://github.com/texane/stlink
  • Note the last version, that works for me is: 10924baac1028d7b615f9e975c6214e3c67726c1 from Jun 07. 2012
  • Here is a zip of this version: stlink-10924ba.zip: Linux stlink tool
  • extract and build it by "./autogen.sh" then "./configure" and finally "make"
  • the tool "st-flash" will be in the main directory
  • connect the device using the mini-USB connector
  • use the command line "./st-flash write T4.bin 0x8000000"
  • replace "T4.bin" in the command line by the desired ".bin" file



Edit | Attach | Refresh | Diffs | More | Revision r1.14 - 18 Dec 2015 - 10:22 - ManuelHuber

Lehrstuhl für Computer Aided Medical Procedures & Augmented Reality    rss.gif