повторить проект

fsdb
Offline
Зарегистрирован: 24.10.2015

Ребята пытаюсь повторить проект на ардиуно нано по подключению датчика TCD1304 

Ссылка тут:

https://hackaday.io/project/18126-dav5-v301-raman-spectrometer/log/53099-using-an-arduino-r3-to-power-the-tcd1304ap-ccd-chip

Помогите понять скетч.

ICG и SH генерируют частоту, мне понятно примерно...

что делает выход MCLK - он же FM по даташиту там должна быть частота вроде как от 0.8 до 2мгрц. а в скетче нет этой геренерации. он же в скетче помечен как выход?

не пойму

/* Original sketch available at:
 * https://hackaday.io/project/18126-dav5-v301-raman-spectrometer/log/53099...
 * 
 * 23LC1024 - Uno:
 * ---------------
 * Pin1 (CS) -- Pin 10 (CS) (with 10K pullup to +5V)
 * Pin2 (SO)  -- Pin 12 (MISO)
 * Pin3 (NU)  -- 10K -- +5V
 * Pin4 Vss -- GND
 * Pin5 (SI)  -- Pin 11 (MOSI)
 * Pin6 (SCK) -- Pin 13 (SCK)
 * Pin7 (HOLD) -- 10K -- +5V
 * Pin8 (V+)  -- +5V
 * 
 * TCD1304 - Arduino Uno R3
 * ------------------------
 * pin 3 (ICG) - D5
 * pin 4 (MCLK) - D3
 * pin 5 (SH)- D6
 */
 
#include <SRAMsimple.h>
#define CSPIN 10       // Default Chip Select Line for Uno (change as needed)
SRAMsimple sram;       //initialize an instance of this class

//#define MENUMODE // comment out for continuous readings 

//#define sbi
#define PIXELS 800 // default: 800 (3648 max). Use 800 for the Uno.

char cmdBuffer[16];
int cmdIndex;
int exposureTime = 12; // play with this for a good exposure time

#define CLOCK PORTD  // use PORTD for the UNO (make room for MOSI, MISO, and SCK for the 23LC1024)
#include <util/delay_basic.h>

#define ICG (1<<5)  // PD5 (Digital Pin 5)
#define MCLK (1<<6) // PD3 (Digital Pin 3)
#define SH (1<<3)   // PD6 (Digital Pin 6)  

// needed to switch to adc-fast mode later
#ifndef cbi
  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

void setup(){
  SPI.begin();                                // start communicating with the memory chip
  byte val;
  // Initialize the clocks.
  DDRD |= (SH | ICG | MCLK); // Set the clock lines to output mode
  CLOCK |= ICG; // Set the integration clear gate high.
  // Enable the serial port.
  Serial.begin(115200);
  #ifdef MENUMODE
    Serial.println("Program start.");
    Serial.println("Serial Monitor Commands:");
    Serial.println("r: read diode array");
    Serial.println("e: decrease exposure time");
    Serial.println("E: increase exposure time");
    Serial.println("Enter choice:");
  #endif
  // Setup timer2 to generate a 1 MHz frequency on PD3 (Pin3) using FastPWM mode (affects pins 3 and 11)
  //Just Pin 3:
  pinMode(3, OUTPUT); // output pin for OCR2B, this is Arduino pin number
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // inverting mode, fast PWM
  TCCR2B = _BV(WGM22) | _BV(CS20); // no prescaling
  OCR2A = 15; // counter limit: 255
  OCR2B = 7; //duty cycle, can't be greater than OCR2A. (OCR2B=0.5*OCR2A for 50% duty cycle)  
  //duty cycle =OCR2B/OCR2A
  
  // faster ADC modes: http://yaab-arduino.blogspot.com/2015/02/fast-sampling-from-analog-input...
  cbi(ADCSRA,ADPS2); // sbi is HIGH, cbi is LOW
  sbi(ADCSRA,ADPS1);
  sbi(ADCSRA,ADPS0);
  // 0 0 1 --> prescaler=2 --> 8 usec per analog reading
  // 0 1 0 --> prescaler=4 --> 8 usec 
  // 0 1 1 --> prescaler=8 --> 12 usec <-- provided best experimental results
  // 1 0 0 --> prescaler=16 --> 20 usec
  // 1 0 1 --> prescaler=32 --> 32 usec
  // 1 1 0 --> prescaler=64 --> 60 usec
  // 1 1 1 --> prescaler=128 ---> 116 usec
}

void readCCD(unsigned int pixels, int expos){
  byte warmUps=20; // number of readings to adjust to new exposure time (set to >10)
  for(uint32_t x=0;x<pixels;x++){
    sram.WriteUnsignedInt(2*x,0); // initialize buffer
  }
  unsigned int timer1=millis();
  for(int y=0;y<20;y++){ // warmup runs
    CLOCK &= ~ICG; // set ICG low
    delayMicroseconds(1); // timing requirement (1000 ns max)
    CLOCK |= SH;   // set SH high 
    delayMicroseconds(1); // timing requirement (1000 ns max)
    CLOCK &= ~SH;  // set SH low
    delayMicroseconds(5); // timing requirement (min 1000ns, typ 5000 ns)
    CLOCK |= ICG;  // set ICG high
    _delay_loop_1(1);  // wait a tick (supposed to be t4 in the datasheet, 20 ns)
    delayMicroseconds(14780);   // delay an entire cycle
    delay(expos);
  }
  for(int y=0;y<24;y++){
    CLOCK &= ~ICG; // set ICG low
    delayMicroseconds(1); // timing requirement (1000 ns max)
    CLOCK |= SH;   // set SH high 
    delayMicroseconds(1); // timing requirement (1000 ns max)
    CLOCK &= ~SH;  // set SH low
    delayMicroseconds(5); // timing requirement (min 1000ns, typ 5000 ns)
    CLOCK |= ICG;  // set ICG high
    _delay_loop_1(1);  // wait a tick (supposed to be t4 in the datasheet, 20 ns)
    delayMicroseconds(128+(4*y));   // delay until the correct first pixel
    //unsigned int timer1,timer2;
    for(int i=y;i<pixels;i+=24){ // should amount to 152 pixel readings
      //timer1=micros();
      sram.WriteUnsignedInt(i*2,analogRead(A0)); // takes about 64 usec
      Serial.print(analogRead(A0)); Serial.print(";");
      //timer2=micros();
      //Serial.println(timer2-timer1);
      delayMicroseconds(40); // delay between readings
    }
    delayMicroseconds(4*(24-y)+52); // skip the last pixels plus trailing dummy outputs
    delay(expos); 
  }
}

void sendData(void){ // Sends diode array data to serial monitor
  for (uint32_t x=0;x<PIXELS;x++){
    if(x>0){Serial.print(";");} // for CSV format
    Serial.print(sram.ReadUnsignedInt(2*x));
  }
  Serial.println();
}

void loop(){
  #ifdef MENUMODE
  // Begin serial commands
    if (Serial.available()){  // Listening for serial monitor commands
      cmdBuffer[cmdIndex++] = Serial.read();
    }
    if (cmdBuffer[0] == 'r'){ // read the CCD (and send data to the serial monitor)
      readCCD(PIXELS,exposureTime);
      sendData();
      Serial.println("Enter choice:");
    }
    else if (cmdBuffer[0] == 'e'){
      if (--exposureTime < 0) exposureTime = 0;
      Serial.print("Exposure time ");
      Serial.println(exposureTime);
    }
    else if (cmdBuffer[0] == 'E'){
      if (++exposureTime > 200) exposureTime = 200;
      Serial.print("Exposure time ");
      Serial.println(exposureTime);
    }
    cmdBuffer[0] = '\0'; // erase the command buffer
    cmdIndex = 0;
  #endif // end of MENUMODE serial commands
  #ifndef MENUMODE
    readCCD(PIXELS,exposureTime);
    sendData();
    //delay(1000);  // optional delay for continuous reading
  #endif
}

 

 

Green
Offline
Зарегистрирован: 01.10.2015

Ну как же нет! В строках 67 - 73 открытым текстом об этом сказано. На 3-м пине будет меандр, с частотой по формуле.

fsdb
Offline
Зарегистрирован: 24.10.2015

Green спасибо что ответили. мы уже вторую неделю вдвоем с товарищем пытаемся победить и никак.
оба купили датчики эти... и сидим)))
у меня есть логический анализатор уровней на 8 каналов. 24мбит...
я же правильно понял - не подключая  сам датчик в теории я должен увидеть стабильно 3 сигнала с ардуины нано/мега
она должна генерировать не зависимо от подключения датчика 3 сигнала на выходе....?
правильно понял я?

d3, d5, d6

 

Лишь только A0 я считываю ответ с самого датчика..

так?

Я просто подключаю анализатор и не вижу например сигнал MCLK (FM) . у меня к роме китайского анализатора ничего нет вот и пытаюсь разобраться. должен не должен быть сигнал... у товарища есть осциллограф старый советский и говорит сигналы очень плохие и не видит MCLK (FM).

 

 

fsdb
Offline
Зарегистрирован: 24.10.2015

еще хотелось бы задать попутный вопрос-мы нашли еще один скетч другого автора и он тоже судя по видео на ютубе - рабочий.
у меня возник вопрос. например автор пишет номер выхода 0х20. на одном из рисунков я вижу что это обозначено как d8, как так получилось что 0х20 это d8. не понимаю как происходит конвертирование. хотелось бы точно понимать на каком пине идет сигнал.

#ifdef ARDUINO_AVR_MEGA2560

#define LAMP 0x20

#define SH 0x40

#define ICG 0x80

#define MCLK 0x10

#else

#define LAMP 0x01

#define SH 0x02

#define ICG 0x04

#define MCLK 0x08

#endif
 
Green
Offline
Зарегистрирован: 01.10.2015

Да, на всех 3х выходах должны быть импульсы. На 3-м пине 1 мгц, с виду.
По поводу 0х20 надо смотреть Ардуино Мега pinout, ну и сам скетч, что бы видеть в какой порт пишется. 8 пин == PH5 == 0х20.

fogary
Offline
Зарегистрирован: 05.03.2016

fsdb пишет:
как так получилось что 0х20 это d8

Похоже - это какие-то битовые маски, т. е. это не номер или адрес порта.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

fsdb пишет:

у меня возник вопрос. например автор пишет номер выхода 0х20. на одном из рисунков я вижу что это обозначено как d8, как так получилось что 0х20 это d8. 

Элементарно.
1) Сначала переводите 16-ричное число (коим является 0x20) в двоичное:  0x20 == 0b00100000
2) Нумерация битов идет с нуля и справа налево. В этом числе единица записана в пятый бит.
3) Далее, если это число присваивается регистру DDRH или PORTH (регистры для работы с портами ввода-вывода), значит единица записывается в пятый бит регистра. 
4) Пятый бит регистра отвечает за пятый пин микроконтророллера Atmega2560 (PH5).
5) Смотрим распиновку платы (Arduino Mega Pinout) и видим, что пин PH5 микроконтроллера Atmega2560 - это пин D8 на плате ардуино.

f3ss1
Offline
Зарегистрирован: 06.03.2021

fsdb пишет:

Ребята пытаюсь повторить проект на ардиуно нано по подключению датчика TCD1304 

Автор, отзовитесь! Пытаюсь сделать то же самое, был бы признателен, если бы помогли знанием!

Здесь как-то можно обменяться почтой не при всех?)

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

f3ss1 пишет:

Здесь как-то можно обменяться почтой не при всех?)

А что вас пугает ? Страшно получить фото интимных мет постороннего человека на почту !?

f3ss1
Offline
Зарегистрирован: 06.03.2021

Конфиденциальность и анонимность как-никак, чтоб ее!