├── LICENSE ├── README.md ├── mousecam.ino ├── readrom.ino ├── readrom_shield.jpg └── readrom_shield_schematic.jpeg /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Simon Winder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino 2 | Various small Arduino sketches 3 | 4 | ## readrom - read data from old EPROM chips 5 | See http://simonwinder.com for details of shield. 6 | http://simonwinder.com/2015/05/how-to-read-old-eproms-with-the-arduino/ 7 | 8 | You can also find a schematic and also a photo of the custom Arduino shield needed for reading the contents of old EPROMS. 9 | 10 | Usage: You have to have a serial connection open at 9600 baud. The program expects a single command which is 'm'. This means list memory. For example if you have a ROM connected you might type "m 0 0400" This will list the memory bytes from location 0 in hex through 0400 in hex. If you want to just look at 16 bytes then you can leave off the end address. 11 | 12 | ## mousecam - interface with a ADNS-3080 based optical flow camera 13 | 14 | This code reads from the camera and outputs data to the terminal. It can capture the motion vectors or else it can dump out whole frames. 15 | 16 | 17 | -------------------------------------------------------------------------------- /mousecam.ino: -------------------------------------------------------------------------------- 1 | #include "SPI.h" 2 | 3 | // these pins may be different on different boards 4 | // this is for the uno 5 | #define PIN_SS 10 6 | #define PIN_MISO 12 7 | #define PIN_MOSI 11 8 | #define PIN_SCK 13 9 | 10 | #define PIN_MOUSECAM_RESET 3 11 | #define PIN_MOUSECAM_CS 2 12 | 13 | #define ADNS3080_PIXELS_X 30 14 | #define ADNS3080_PIXELS_Y 30 15 | 16 | #define ADNS3080_PRODUCT_ID 0x00 17 | #define ADNS3080_REVISION_ID 0x01 18 | #define ADNS3080_MOTION 0x02 19 | #define ADNS3080_DELTA_X 0x03 20 | #define ADNS3080_DELTA_Y 0x04 21 | #define ADNS3080_SQUAL 0x05 22 | #define ADNS3080_PIXEL_SUM 0x06 23 | #define ADNS3080_MAXIMUM_PIXEL 0x07 24 | #define ADNS3080_CONFIGURATION_BITS 0x0a 25 | #define ADNS3080_EXTENDED_CONFIG 0x0b 26 | #define ADNS3080_DATA_OUT_LOWER 0x0c 27 | #define ADNS3080_DATA_OUT_UPPER 0x0d 28 | #define ADNS3080_SHUTTER_LOWER 0x0e 29 | #define ADNS3080_SHUTTER_UPPER 0x0f 30 | #define ADNS3080_FRAME_PERIOD_LOWER 0x10 31 | #define ADNS3080_FRAME_PERIOD_UPPER 0x11 32 | #define ADNS3080_MOTION_CLEAR 0x12 33 | #define ADNS3080_FRAME_CAPTURE 0x13 34 | #define ADNS3080_SROM_ENABLE 0x14 35 | #define ADNS3080_FRAME_PERIOD_MAX_BOUND_LOWER 0x19 36 | #define ADNS3080_FRAME_PERIOD_MAX_BOUND_UPPER 0x1a 37 | #define ADNS3080_FRAME_PERIOD_MIN_BOUND_LOWER 0x1b 38 | #define ADNS3080_FRAME_PERIOD_MIN_BOUND_UPPER 0x1c 39 | #define ADNS3080_SHUTTER_MAX_BOUND_LOWER 0x1e 40 | #define ADNS3080_SHUTTER_MAX_BOUND_UPPER 0x1e 41 | #define ADNS3080_SROM_ID 0x1f 42 | #define ADNS3080_OBSERVATION 0x3d 43 | #define ADNS3080_INVERSE_PRODUCT_ID 0x3f 44 | #define ADNS3080_PIXEL_BURST 0x40 45 | #define ADNS3080_MOTION_BURST 0x50 46 | #define ADNS3080_SROM_LOAD 0x60 47 | 48 | #define ADNS3080_PRODUCT_ID_VAL 0x17 49 | 50 | void mousecam_reset() 51 | { 52 | digitalWrite(PIN_MOUSECAM_RESET,HIGH); 53 | delay(1); // reset pulse >10us 54 | digitalWrite(PIN_MOUSECAM_RESET,LOW); 55 | delay(35); // 35ms from reset to functional 56 | } 57 | 58 | int mousecam_init() 59 | { 60 | pinMode(PIN_MOUSECAM_RESET,OUTPUT); 61 | pinMode(PIN_MOUSECAM_CS,OUTPUT); 62 | 63 | digitalWrite(PIN_MOUSECAM_CS,HIGH); 64 | 65 | mousecam_reset(); 66 | 67 | int pid = mousecam_read_reg(ADNS3080_PRODUCT_ID); 68 | if(pid != ADNS3080_PRODUCT_ID_VAL) 69 | return -1; 70 | 71 | // turn on sensitive mode 72 | mousecam_write_reg(ADNS3080_CONFIGURATION_BITS, 0x19); 73 | 74 | return 0; 75 | } 76 | 77 | void mousecam_write_reg(int reg, int val) 78 | { 79 | digitalWrite(PIN_MOUSECAM_CS, LOW); 80 | SPI.transfer(reg | 0x80); 81 | SPI.transfer(val); 82 | digitalWrite(PIN_MOUSECAM_CS,HIGH); 83 | delayMicroseconds(50); 84 | } 85 | 86 | int mousecam_read_reg(int reg) 87 | { 88 | digitalWrite(PIN_MOUSECAM_CS, LOW); 89 | SPI.transfer(reg); 90 | delayMicroseconds(75); 91 | int ret = SPI.transfer(0xff); 92 | digitalWrite(PIN_MOUSECAM_CS,HIGH); 93 | delayMicroseconds(1); 94 | return ret; 95 | } 96 | 97 | struct MD 98 | { 99 | byte motion; 100 | char dx, dy; 101 | byte squal; 102 | word shutter; 103 | byte max_pix; 104 | }; 105 | 106 | void mousecam_read_motion(struct MD *p) 107 | { 108 | digitalWrite(PIN_MOUSECAM_CS, LOW); 109 | SPI.transfer(ADNS3080_MOTION_BURST); 110 | delayMicroseconds(75); 111 | p->motion = SPI.transfer(0xff); 112 | p->dx = SPI.transfer(0xff); 113 | p->dy = SPI.transfer(0xff); 114 | p->squal = SPI.transfer(0xff); 115 | p->shutter = SPI.transfer(0xff)<<8; 116 | p->shutter |= SPI.transfer(0xff); 117 | p->max_pix = SPI.transfer(0xff); 118 | digitalWrite(PIN_MOUSECAM_CS,HIGH); 119 | delayMicroseconds(5); 120 | } 121 | 122 | // pdata must point to an array of size ADNS3080_PIXELS_X x ADNS3080_PIXELS_Y 123 | // you must call mousecam_reset() after this if you want to go back to normal operation 124 | int mousecam_frame_capture(byte *pdata) 125 | { 126 | mousecam_write_reg(ADNS3080_FRAME_CAPTURE,0x83); 127 | 128 | digitalWrite(PIN_MOUSECAM_CS, LOW); 129 | 130 | SPI.transfer(ADNS3080_PIXEL_BURST); 131 | delayMicroseconds(50); 132 | 133 | int pix; 134 | byte started = 0; 135 | int count; 136 | int timeout = 0; 137 | int ret = 0; 138 | for(count = 0; count < ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y; ) 139 | { 140 | pix = SPI.transfer(0xff); 141 | delayMicroseconds(10); 142 | if(started==0) 143 | { 144 | if(pix&0x40) 145 | started = 1; 146 | else 147 | { 148 | timeout++; 149 | if(timeout==100) 150 | { 151 | ret = -1; 152 | break; 153 | } 154 | } 155 | } 156 | if(started==1) 157 | { 158 | pdata[count++] = (pix & 0x3f)<<2; // scale to normal grayscale byte range 159 | } 160 | } 161 | 162 | digitalWrite(PIN_MOUSECAM_CS,HIGH); 163 | delayMicroseconds(14); 164 | 165 | return ret; 166 | } 167 | 168 | void setup() 169 | { 170 | pinMode(PIN_SS,OUTPUT); 171 | pinMode(PIN_MISO,INPUT); 172 | pinMode(PIN_MOSI,OUTPUT); 173 | pinMode(PIN_SCK,OUTPUT); 174 | 175 | SPI.begin(); 176 | SPI.setClockDivider(SPI_CLOCK_DIV32); 177 | SPI.setDataMode(SPI_MODE3); 178 | SPI.setBitOrder(MSBFIRST); 179 | 180 | Serial.begin(38400); 181 | 182 | if(mousecam_init()==-1) 183 | { 184 | Serial.println("Mouse cam failed to init"); 185 | while(1); 186 | } 187 | } 188 | 189 | char asciiart(int k) 190 | { 191 | static char foo[] = "WX86*3I>!;~:,`. "; 192 | return foo[k>>4]; 193 | } 194 | 195 | byte frame[ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y]; 196 | 197 | void loop() 198 | { 199 | #if 0 200 | 201 | // if enabled this section grabs frames and outputs them as ascii art 202 | 203 | if(mousecam_frame_capture(frame)==0) 204 | { 205 | int i,j,k; 206 | for(i=0, k=0; i>8); 85 | digitalWrite(pin_sel_high, HIGH); 86 | //delay(10); 87 | digitalWrite(pin_sel_high, LOW); 88 | set_port_as_input(); 89 | digitalWrite(pin_cs, LOW); 90 | //delay(10); 91 | byte val = read_port_value(); 92 | digitalWrite(pin_cs, HIGH); 93 | 94 | return val; 95 | } 96 | 97 | char cmdbuf[64]; 98 | int cmd_index; 99 | 100 | void setup() 101 | { 102 | // put your setup code here, to run once: 103 | set_port_as_input(); 104 | 105 | pinMode(pin_sel_low, OUTPUT); 106 | digitalWrite(pin_sel_low, LOW); 107 | 108 | pinMode(pin_sel_high, OUTPUT); 109 | digitalWrite(pin_sel_high, LOW); 110 | 111 | pinMode(pin_cs, OUTPUT); 112 | digitalWrite(pin_cs, HIGH); 113 | 114 | Serial.begin(9600); 115 | 116 | cmd_index = 0; 117 | cmdbuf[0] = 0; 118 | } 119 | 120 | void loop() 121 | { 122 | // put your main code here, to run repeatedly: 123 | if(Serial.available() > 0) 124 | { 125 | char b = Serial.read(); 126 | if(b!='\n') 127 | { 128 | if(cmd_index<63) 129 | cmdbuf[cmd_index++] = b; 130 | } 131 | else 132 | { 133 | cmdbuf[cmd_index] = 0; 134 | if(cmd_index>0) 135 | { 136 | if(cmdbuf[0]=='m' && cmdbuf[1]==' ') 137 | { 138 | short addr_start; 139 | short addr_end; 140 | int num = sscanf(cmdbuf+2, "%x%x", &addr_start, &addr_end); 141 | if(num==0) 142 | Serial.println('?'); 143 | else 144 | { 145 | if(num==1) 146 | addr_end = addr_start + 16; 147 | short addr = addr_start; 148 | short n = 0; 149 | while(addr!=addr_end) 150 | { 151 | if(n==0) 152 | { 153 | char buf[16]; 154 | sprintf(buf, "\n%04x ", addr); 155 | Serial.print(buf); 156 | } 157 | n++; 158 | if(n==16) 159 | n = 0; 160 | 161 | byte data = read_cycle(addr); 162 | char buf[16]; 163 | sprintf(buf, "%02x ", data); 164 | Serial.print(buf); 165 | addr++; 166 | } 167 | } 168 | Serial.println(' '); 169 | } 170 | else 171 | { 172 | Serial.println('?'); 173 | } 174 | 175 | cmd_index = 0; 176 | } 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /readrom_shield.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/impressivemachines/Arduino/61dfd90cf7a62e87527b9ca3b257444f55481fee/readrom_shield.jpg -------------------------------------------------------------------------------- /readrom_shield_schematic.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/impressivemachines/Arduino/61dfd90cf7a62e87527b9ca3b257444f55481fee/readrom_shield_schematic.jpeg --------------------------------------------------------------------------------