TSL3301

Dependencies:   BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed

Fork of DISCO-F746NG_TSL3301 by Yaroslav Krainyk

main.cpp

Committer:
oZGi
Date:
2018-03-20
Revision:
2:6d7063605e3a
Parent:
1:979d4820e32a
Child:
3:cb16c3af98de

File content as of revision 2:6d7063605e3a:

#include "mbed.h"
#include "TS_DISCO_F746NG.h"
#include "LCD_DISCO_F746NG.h"

LCD_DISCO_F746NG lcd;
int line = 1;

DigitalIn miso(D8);
DigitalOut mosi(D7);
DigitalOut clk(D6);

unsigned char lcam_buffer[102];
unsigned char max_area;

void lcam_pulse(void) { 
    clk = 1;
    clk = 0;
}

void lcam_pulse_clock(uint8_t times){ 
    for(unsigned char i = 0; i < times; i++)
    {
        lcam_pulse();
    }
}

void lcam_send(uint8_t value){ 
    // Start bit
    mosi = 0;
    lcam_pulse();
    // Send 8 bits to camera
    for(unsigned char i = 0; i < 8; i++)
    {
        mosi = ((value >> i) & 1);
        lcam_pulse();
    }
    // Stop bit
    mosi = 1;
    lcam_pulse();
}

void lcam_reset(void){ 
    wait_ms(1);
  
    // 10 clock impulsions with SDIN held high to clear the receiver logic
    mosi = 1;
    lcam_pulse_clock(10);
    // 3 reset instructions to clear the control logic
    lcam_send(0x1b);
    lcam_send(0x1b);
    lcam_send(0x1b);
    // 30 clock impulsions to assure the state of SDOUT
    lcam_pulse_clock(30);
  
    // register write mode
    lcam_send(0X5F);
    // Clear mode register (single chip, not sleep)
    lcam_send(0x00);
}

void lcam_setup(void){ 
    lcam_reset();
  
  // set inputs and outputs
  //clk = 1;
  //pin_mode(LCAM_PORT, LCAM_SDIN, 1);
  //pin_mode(LCAM_PORT, LCAM_SDOUT, 0);
  // make sure the clock is cleared
  clk = 0;
  
  // Left offset
  lcam_send(0x40);
  lcam_send(0);
  // Left gain
  lcam_send(0x41);
  lcam_send(15);
  // Middle offset
  lcam_send(0x42);
  lcam_send(0);
  // Middle gain
  lcam_send(0x43);
  lcam_send(15);
  // Right offset
  lcam_send(0x44);
  lcam_send(0);
  // Right gain
  lcam_send(0x45);
  lcam_send(15);
}

void lcam_startintegration(void){ 
      // Send start integration command
    lcam_send(0x08);
    // delayed until the pixel reset cycle has been completed (22-clock delay)
    lcam_pulse_clock(22);
}

void lcam_endintegration(void){ 
    // Sample int command
    lcam_send(0x10);
    // pixel reset sequence is initiated, requires 22 clocks
    lcam_pulse_clock(22);
}

void lcam_integrate(unsigned int microseconds){ 
    lcam_startintegration();
    wait_us(microseconds);
    lcam_endintegration();
}

unsigned char* lcam_getdata(void){ 
     return lcam_buffer;
}

void lcam_read(void){ 
    unsigned char i, pixel_bit, pixel;
  // Read pixel command
  lcam_send(0x02);
  // 44-clock cycle delay until the first pixel data is output
  lcam_pulse_clock(44);
  // Read the 102 pixels from the camera
  for(i = 0; i < 102; i++)
  {
    pixel = 0;
    // pulse the pixel start bit (SDOUT = 0)
    lcam_pulse();
    // read a byte, bit by bit
    for(pixel_bit = 0; pixel_bit < 8; pixel_bit++)
    {
      clk = 1;
      // read pin while clock is at 1
      pixel |= (((miso) & 1) << pixel_bit);
      clk = 0;
    }
    // store byte to buffer
    lcam_buffer[i] = pixel;
    // pulse the pixel stop bit (SDOUT = 1)
    lcam_pulse();
}
}

unsigned char lcam_getpic(void)
{
  unsigned char i, value, highest = 0, max_region = 0;
  unsigned int average = 0;
  for(i = 0; i < 25; i++)
  {
    // take 4-byte average and divide by 4 (shift to right by 2)
    value = ((lcam_buffer[i*4] + lcam_buffer[i*4+1] + lcam_buffer[i*4+2] + lcam_buffer[i*4+3]) >> 2);
    if(value > highest)
    {
      highest = value;
      max_region = i;
    }
    average += value;
  }
  
  average /= 25;
  
  if(highest > average + 30)
  {
    return max_region;
  }
  else
  {
    return 0;
  }
}

int main() {  
    lcam_setup();
    while(1) {
        if (line == 10){
            line = 1;
            }
        
        lcd.Clear(LCD_COLOR_WHITE);
        lcd.SetBackColor(LCD_COLOR_WHITE);
        lcd.SetTextColor(LCD_COLOR_RED);
        
        lcam_integrate(10);
        
        lcam_read();
        
        max_area = lcam_getpic();
        
        lcd.DisplayStringAt(0, LINE(line), (uint8_t *)max_area, CENTER_MODE);
        line +=1;
        wait_ms(200);
    }
}