Hello all,
I try to use an optical flow sensor to drive a strip led from a teensy 3.6 .
- I can read the sensor which is spi connected (pins used : 9, 10, 11, 12, 13)
- I can command the leds using octows2811 library.
I cannot do both, as soon as I use "led.show" it blocks...
Any idea?
Thank's , y.
The code :
I try to use an optical flow sensor to drive a strip led from a teensy 3.6 .
- I can read the sensor which is spi connected (pins used : 9, 10, 11, 12, 13)
- I can command the leds using octows2811 library.
I cannot do both, as soon as I use "led.show" it blocks...
Any idea?
Thank's , y.
The code :
Code:
/* Copyright (C) 2015 Kristian Sloth Lauszus. All rights reserved. Send data from ADNS3080 as raw bytes. Based on the code by Randy Mackay. DIYDrones.com
Kristian Sloth Lauszus ---- http://www.lauszus.com ----- lauszus@gmail.com
https://www.pjrc.com/teensy/td_libs_SPI.html
*/
// ********************* octo *******************
#include <OctoWS2811.h>
#define RED 0x010000
#define GREEN 0x000100
#define BLUE 0x000001
#define YELLOW 0x010100
#define PINK 0x010001
#define ORANGE 0x000101
#define WHITE 0x010101
const int ledsPerStrip = 60;
DMAMEM int displayMemory[ledsPerStrip*6];
int drawingMemory[ledsPerStrip*6];
const int config = WS2811_GRB | WS2811_800kHz;
OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
// ********************* 3080 *********************
#include <SPI.h>
SPISettings spiSettings(2e6, MSBFIRST, SPI_MODE3); // 2 MHz, mode 3
// Register Map for the ADNS3080 Optical OpticalFlow Sensor
#define ADNS3080_PRODUCT_ID 0x00
#define ADNS3080_MOTION 0x02
#define ADNS3080_DELTA_X 0x03
#define ADNS3080_DELTA_Y 0x04
#define ADNS3080_SQUAL 0x05
#define ADNS3080_CONFIGURATION_BITS 0x0A
#define ADNS3080_Extended_Config 0x0B
#define ADNS3080_MOTION_CLEAR 0x12
#define ADNS3080_FRAME_CAPTURE 0x13
#define ADNS3080_MOTION_BURST 0x50
// ADNS3080 hardware config
#define ADNS3080_PIXELS_X 30
#define ADNS3080_PIXELS_Y 30
// Id returned by ADNS3080_PRODUCT_ID register
#define ADNS3080_PRODUCT_ID_VALUE 0x17
// pour teensy 3.6 voir https://www.pjrc.com/teensy/td_libs_SPI.html
// these pins may be different on different boards
static const uint8_t RESET_PIN = 9;
// #define PIN_SCK 13
// #define PIN_MISO 12
// #define PIN_MOSI 11
static const uint8_t SS_PIN = SS; // Pin 10 #define PIN_SS 10
static int32_t x, y;
static float d ;
char art[] = "WX86*3I>!;~:,`. "; //
void setup()
{
Serial.begin(115200) ; while (!Serial); // Wait for serial port to open
// ***************** octo *********************
leds.begin( ) ;
leds.show ( ) ;
for (int i = 0 ; i<610 ; i++) { leds.setPixel(60*6+i%60, 0x010000 ); leds.show(); leds.setPixel(60*6+i%60, 0x000000 ); delay(5); } ;
// ********************** 3080 ****************
SPI.begin();
// Set SS and reset pin as output
pinMode(SS_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
reset();
uint8_t id = spiRead(ADNS3080_PRODUCT_ID);
if (id == ADNS3080_PRODUCT_ID_VALUE) Serial.println(F("ADNS-3080 found yj")); else { Serial.print(F("Could not find ADNS-3080: ")); Serial.println(id, HEX); while (1); }
// uint8_t config = spiRead(ADNS3080_CONFIGURATION_BITS); spiWrite(ADNS3080_CONFIGURATION_BITS, config | 0x10); // Set resolution to 1600 counts per inch 400 par default
while (spiRead(ADNS3080_Extended_Config) & 0x80) ; // attendre qu il soit possible d ecrire
spiWrite(0x19, 0xe0); // 2000Hz
spiWrite(0x1a, 0x2e); // 2000Hz
delay(10);
Serial.println(F(" Setup done "));
}
void loop()
{
#if 1
updateSensor(); delayMicroseconds(30000); colorWipe(RED);
#else
Serial.write("start\n"); printPixelData(); Serial.flush(); delay(50);
#endif
}
char str[32] ;
void updateSensor(void) {
// Read sensor
uint8_t buf[7]; spiRead(ADNS3080_MOTION_BURST, buf, 7); uint8_t motion = buf[0];
if (motion & 0x10) Serial.println(F("ADNS-3080 overflow\n")); // Check if we've had an overflow
else if (motion & 0x80)
// else
{
int8_t dx = buf[1]; int8_t dy = buf[2]; uint8_t surfaceQuality = buf[3]; d += (float) sqrt( sq((float)dx) + sq((float)dy) ) ; // x += dx; y += dy;
sprintf(str, "%2x %05i,%4i %5i,%4i %3i %3i %3i %3i", motion, x, dx, y, dy, surfaceQuality, buf[4], buf[5], buf[6]); Serial.println(str); Serial.println(d); Serial.flush();
}
// else Serial.println(motion, HEX);
// delay(10);
}
void colorWipe(int color)
{ int i=6*60 + (int)d % 60 ;
leds.setPixel(i, color);
//leds.show();
leds.setPixel(i, 0 );
}
void reset(void) { digitalWrite(RESET_PIN, HIGH); delayMicroseconds(10); digitalWrite(RESET_PIN, LOW); delayMicroseconds(500); }
// Will cause the Delta_X, Delta_Y, and internal motion registers to be cleared
void clearMotion() { spiWrite(ADNS3080_MOTION_CLEAR, 0xFF); x = y = 0; } // Writing anything to this register will clear the sensor's motion registers
void spiWrite(uint8_t reg, uint8_t data) { spiWrite(reg, &data, 1); }
void spiWrite(uint8_t reg, uint8_t *data, uint8_t length) {
SPI.beginTransaction(spiSettings);
digitalWrite(SS_PIN, LOW);
SPI.transfer(reg | 0x80); // Indicate write operation
delayMicroseconds(75); // Wait minimum 75 us in case writing to Motion or Motion_Burst registers
SPI.transfer(data, length); // Write data
digitalWrite(SS_PIN, HIGH);
SPI.endTransaction();
}
uint8_t spiRead(uint8_t reg) { uint8_t buf; spiRead(reg, &buf, 1); return buf;}
void spiRead(uint8_t reg, uint8_t *data, uint8_t length)
{
SPI.beginTransaction(spiSettings);
digitalWrite(SS_PIN, LOW);
SPI.transfer(reg); // Send register address
delayMicroseconds(75); // Wait minimum 75 us in case writing to Motion or Motion_Burst registers
memset(data, 0, length); // Make sure data buffer is 0
SPI.transfer(data, length); // Write data
digitalWrite(SS_PIN, HIGH);
SPI.endTransaction();
}
void printPixelData(void)
{
bool isFirstPixel = true; //char str[16];
spiWrite(ADNS3080_FRAME_CAPTURE, 0x83); // Write to frame capture register to force capture of frame
delayMicroseconds(1510); //Wait 3 frame periods + 10 micro-seconds for frame to be captured Minimum frame speed is 2000 frames/second so 1 frame = 500 µ seconds. So 500 x 3 + 10 = 1510
for (uint8_t i = 0; i < ADNS3080_PIXELS_Y; i++) // Display the pixel data
{
for (uint8_t j = 0; j < ADNS3080_PIXELS_X; j++)
{
uint8_t regValue = spiRead(ADNS3080_FRAME_CAPTURE);
if (isFirstPixel && !(regValue & 0x40)) { Serial.println(F("Failed to find first pixel")); goto reset; }
isFirstPixel = false;
// uint8_t pixelValue = regValue << 2; // Only lower 6 bits have data
uint8_t pixelValue = (regValue & 0x3f)+32 ; // ((regValue & 0x3f)<<2) >> 4; // Only lower 6 bits have data
// Serial.write( pixelValue );
// Serial.write((char)pixelValue); Serial.print(' '); //Serial.write(art[pixelValue]); Serial.print(' '); //
// sprintf(str, "%2i" , (int) pixelValue-32 ); Serial.print(str); //Serial.write(art[pixelValue]); Serial.print(' '); //
Serial.write( pixelValue-32 );
}
// Serial.println(); // yj
Serial.flush();
}
reset:
reset(); // Hardware reset to restore sensor to normal operation
}