Arduino Code Examples

This Page is all about my code examples for the projects I make

Motor Control Targeting Interface Program using a Bourns 2-Bit Quadrature code encoder (64 PPR [pulses per revolution]

/*When you turn the rotary encoder clockwise, the angular displacement is increased;

  when you turn it counterclockwise, the displacement is decreased.
  If you press the switch on the rotary encoder, the readings will return to zero
  Original code can be found here://Email: support@sunfounder.com
  //Website: www.sunfounder.com
  //2015.5.7/
  **Although this is in the Public Domain, I have created a "Creative Commons License" for this work,
  the reason is, I made enough mod's and put in many hours of work to make this program accurate and
  efficient as part of a much larger project @ Hackaday.com, the DAV5 3D Printable Raman Spectrometer.
  There are individuals there that have engaged in "intellectual theft" and not bothered to give credit
  where credit was certainly due, so I believe I have no choice but to go this route since I have put in
  2 years of very hard work on this.**
  The creative commons license can be viewed here: https://thequantumhub.blog/
  I have modified this code to accomodate my diffraction grating turret for
  the DAV5 Raman 3D printable Spectrometer (http://hackaday.io/project/18126-dav5-v301-raman-spectrometer)
  Written and modified by David H Haffner SR 10/18/2017
  Full project details can be found here @ https://hackaday.io/project/18126-dav5-v301-raman-spectrometer
  This program is also in the public domain @ https://playground.arduino.cc/Main/KY-040EncodeUsedToControlAHolographicDiffractionGratingForARamanSpectrometer
  It utilizes a Bourns 2-Bit Quadrature code encoder (64 PPR [pulses per revolution] to control the holographic diffraction grating
  at steps of 1 & -1, each pin (SW,DT and CLK) has a 0.1uf ceramic cap for decoupling,
  this is more effective for rise time spike removal. There is one LED that blinks twice to indicate system ready.
  This is accomplished by adjusting both "StepsToTake and RotoryPosition," they are in direct relation to steps per revolution
  of the internal shaft according to the type of stepper motor you are using (mine is a 28-YBJ-48).Fine tuning can be done by playing between
  STEPS (per revolution of shaft) and Speed, this will ensure smoother transitions when turning the encoder for fewer misses.
  If you press the switch on the rotary encoder, the readings will return to approx zero 0.21 percent error.
  a 0.1uf ceramic Cap is placed @ PinSW (4) to + (the reason for the pin pullup).
  The formula in this sketch is derived from the specifications of the 28-YBJ-48 stepper MTR
  which has a step angle of 5.62deg, to convert degrees into nanometers you 1st have to convert
  degrees into radians {RAD}, we do this for the 1st specification which is 5.625deg = 0.09817474 {RAD}
  this # is then divided by the equitorial radius of the Earth which is 3,963.2 miles.
  Our new value would then be, 0.000024772 miles (NM), convert this into centimeters, (3.986667)
  Now with this #, we multiply it by the constant of 1 (NM) = 1609344e+012 miles *(Variable)/ 7
  gives us our converting factor from encoder position count to nanometer counts.
  Sketch uses 9202 bytes (3%) of program storage space. Maximum is 253952 bytes.
  Global variables use 519 bytes (6%) of dynamic memory, leaving 7673 bytes for local variables. Maximum is 8192 bytes.
  • /
  1. include <digitalWriteFast.h>
  2. include <math.h>
  3. include <Wire.h>
  4. include <LiquidCrystal_I2C.h>
  5. include “Stepper.h”
  6. define STEPS 64 // Number of steps for one revolution of Internal shaft

// 2048 steps for one revolution of External shaft LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

double double_x = 3.986667 * 1.609344e+012 * 0 / 7;

volatile boolean TurnDetected; // need volatile for Interrupts volatile boolean rotationdirection; // CW or CCW rotation

  1. define PinNum 2 // Generating interrupts using CLK signal
  2. define PinNum 3 // Reading DT signal
  3. define PinNum 4 // Reading Push Button switch

int RotaryPosition = 0; // To store Stepper Motor Position int PrevPosition; // Previous Rotary position Value to check accuracy int StepsToTake; // How much to move Stepper

// Setup of proper sequencing for Motor Driver Pins // In1, In2, In3, In4 in the sequence 1-3-2-4 Stepper small_stepper(STEPS, 8, 10, 9, 11);

// Interrupt routine runs if CLK goes from HIGH to LOW void isr() {

  static unsigned long                lastInterruptTime = 0;
  unsigned long                       interruptTime = millis();
  //If interrupts come faster than 5ms, assume it's a bounce and ignore
  if (interruptTime - lastInterruptTime > 5) {
    if (!digitalReadFast(3))
      rotationdirection = digitalReadFast(2);
    else
      rotationdirection = !digitalReadFast(2);
  }
  lastInterruptTime = interruptTime;
  TurnDetected = true;

}

void setup () {

  lcd.begin(20, 4);        // initialize the lcd for 20 chars 4 lines, turn on backlight
  // ------- Quick 3 blinks of backlight  -------------
  for (int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
  // Print a message to the LCD.
  lcd.print("SYSTEM RDY");
  lcd.setCursor(10, 0);
  lcd.print(" Mega 2560");// system ready wired to Pin#13 built-in LED (blinks twice to indicate "system ready.")
  lcd.setCursor(0, 1);
  lcd.print("POS:");//CCW or CC
  lcd.setCursor(0, 2);
  lcd.print("Nanomtrs");// Float Position corrected
  Serial.begin(115200);
  delay(1000);
  pinModeFast(2, INPUT);
  attachInterrupt (0, 2, CHANGE);
  pinModeFast(3, INPUT);
  attachInterrupt (1, 3, CHANGE);
  pinModeFast(4, INPUT_PULLUP);// pullup resistor needed for switch stability
  digitalWriteFast(4, HIGH); // Pull-Up resistor for switch
  attachInterrupt (0, isr, FALLING); // interrupt 0 always connected to pin 2 on Arduino UNO/Mega 2560

}

void loop () {

  small_stepper.setSpeed(10); //Max seems to be 700
  if (!(digitalReadFast(4))) {   // check if button is pressed
    if (RotaryPosition == 0.998) {  // check if button was already pressed
    } else {
      small_stepper.step(RotaryPosition * 0.998);
      RotaryPosition = 0; // Reset position to ZERO ("home" position)
      lcd.print(fabs ( 3.986667 * 1.609344 * (PrevPosition) / 7) ); // absolute value of a float
    }
    bool reading = digitalReadFast(4);
    if (reading == ERROR_SEQUENCE) { //ERROR_SEQUENCE  defined as 0b10101010
      // pinNum is not a const and will always return as HIGH
    }
  }
  // Runs if rotation was detected
  if (TurnDetected)  {
    PrevPosition = RotaryPosition; // Save previous position in variable
    if (rotationdirection) {
      RotaryPosition = RotaryPosition - 1;
      lcd.setCursor(8, 1);
      lcd.print(RotaryPosition);
    } // decrase Position by 1
    else {
      RotaryPosition = RotaryPosition + 1;
      lcd.setCursor(13, 1);
      lcd.print(RotaryPosition);
    } // increase Position by 1
    TurnDetected = false;  // do NOT repeat IF loop until new rotation detected
    // Which direction to move Stepper motor
    if ((PrevPosition + 1) == RotaryPosition) { // Move motor CW
      StepsToTake = 1;
      small_stepper.step(StepsToTake);
      lcd.setCursor(15, 2);
      lcd.print(fabs(+(PrevPosition) * 0.963)); // absolute value of a float, steps in + direction
    }
    if ((RotaryPosition + 1) == PrevPosition) { // Move motor CCW
      StepsToTake = -1;
      small_stepper.step(StepsToTake);
      lcd.setCursor(9, 2);
      lcd.print(fabs(-(PrevPosition) * 0.963)); // absolute value of a float, steps in - direction
    }
  }

}

 

PLX-DAQ v2.11 64-Bit Windows 10

/*

  PLX-DAQ v2.11 64_bitfor Windows 10. Big thanks to Net'Devil, this is his baby and it is beautiful!
  I have modified the ReadAnalogVoltage sketch to include both A0 and A1 for a dual trace read coming
  from a 555 TTL timer chip (acting as a pulse generator,) 
  The Baud rate @ 19200 is what works for me in Excel 2016 on Windows 10, it's best to experiment which speed works best
  since it is dependent on the right delay value for data transfer.
  The code below as it appears in excel on my CPU uses two columns, the choice is yours depending on what UR doing.
  The 555 TTL timer schematic pulse generator and video demonstration can be found here at my website;
  https://thequantumhub.blog/
  This example code is in the public domain.
  http://www.arduino.cc/en/Tutorial/ReadAnalogVoltage
  • /

unsigned long int milli_time; //variable to hold the time

void setup() {

  Serial.begin(19200);               //Fastest baudrate
  Serial.println("CLEARDATA");        //This string is defined as a
  // commmand for the Excel VBA
  // to clear all the rows and columns
  Serial.println("LABEL,Computer Time,Time (Milli Sec.),Volt,Time2 (Milli Sec.)");
  //LABEL command creates label for
  // columns in the first row with bold font

} void loop() {

  milli_time = millis();
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  Serial.print("DATA,TIME,");
  Serial.print(milli_time);
  Serial.print(",");
  Serial.println(voltage);
  delay(50);
  milli_time = millis();
  // read the input on analog pin 0:
  int sensorValue1 = analogRead(A1);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage1 = sensorValue1 * (5.0 / 1023.0);
  Serial.print("DATA,TIME,");
  Serial.print(milli_time);
  Serial.print(",");
  Serial.println(voltage1);
  delay(50);                    //Take samples every one second

}

This is the firmware for controlling the V3.01 Turret grating control mount

/* Program 1 REV B

  Updated 7/01/2017 @ 06:43:AM
  Code concept and project design by David H Haffner Sr.
  Stepper program for the 28YBJ-48 (stepper MTR) and ULN2003 driver
  This particular stepper motor is 5.625 degrees per step
  /64
  Speed is controlled by a delay between each step.
  The longer the delay the slower the rotation.
  That delay value is obtained by reading and analog-to-digital
  cover (A0 in this case/50K trimmer POT) which gives a value from 0 to 1023.
  The value is divided by 4 and add 10 for a delay
  in milliseconds:delay(analogRead(0)/4 +10)
  For faster speeds change 10 to say 2.
  This is calculated between every step to vary speed while stepping.
  I incorporated unsigned long int Val, in order read a little bit more of the AN/Map
  A nice feature of unsigned ints: if a val is unsigned, then val / 4 is optimized by
  the compiler into a bit shift, much more efficient than the actual division you would
  get if val was signed.
  Further incorporated a pin array;//read the pushbutton value into a variable
  int sensorVal[] = { digitalRead [2][3] };//SW1 pin2 & SW2 pin3
  This will illuminat LED's #10(W) and LED #12(bl) to indicate that the switches
  on HIGH. These values are then displayed on the LCD menu on line 3 as a monitor
  of the switches values.
  // set the LCD address to 0x27 or 0x3F for a 20 chars 4 line display
  // Set the pins on the I2C chip used for LCD connections:
  //                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
  The commands below will be compiled into machine code and uploaded
  to the microcontroller.
  This is in the public domain.
  Compiled size 6646 bytes.
  • /
  1. include <LiquidCrystal_I2C.h>
  2. include

const int yellow = 7; // M1

const int orange = 5; // M2

const int brown = 6; // M3

const int blue = 4; // M4

const int CW = 2; //Sw1 in schematic

const int CCW = 3; //Sw2 in schematic

unsigned long int val = (analogRead(A0) / 4 + 10);

unsigned long int val1 = (analogRead(‘…’) * 4 + 2);// scale it to use it with the steppermtr (value between 0 and 175)

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

void setup() {

  // initialize digital pin LED_BUILTIN (13) as an output.
  pinMode(LED_BUILTIN, OUTPUT);//Modified "blink" sequence (2)millisec in-step/W/MTR sequence
  pinMode(10, OUTPUT);// this is the LED pin for sensor val prgm
  pinMode(12, OUTPUT);// this is for LED pin 12 sensor Val prgm
  digitalWrite(CW, 1); // pull up on
  digitalWrite(CCW, 1); // pull up on
  pinMode(blue, OUTPUT);
  pinMode(brown, OUTPUT);
  pinMode(orange, OUTPUT);
  pinMode(yellow, OUTPUT);
  // all coils off
  digitalWrite(blue, 0);
  digitalWrite(brown, 0);
  digitalWrite(orange, 0);
  digitalWrite(yellow, 0);
  lcd.begin(20, 4);        // initialize the lcd for 20 chars 4 lines, turn on backlight
  // ------- Quick 3 blinks of backlight  -------------
  for (int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
  // Print a message to the LCD.
  lcd.print("AN/MAP:");
  lcd.setCursor(16, 0);
  lcd.print("0-5V");
  lcd.setCursor(0, 1);
  lcd.print("Direction:");//CCW or CC
  lcd.setCursor(0, 3);
  lcd.print("SwitchState:");//4th line for version display
  lcd.setCursor(0, 2);
  lcd.print("DIV:");
  Serial.begin(115200);

}

void loop() {

  // read the input on :
  for (int i = 0; i < 6; i++) {
    val1 = analogRead(i);
    delay(10);
    // Convert the analog reading (which goes from 0 - 1023) to voltage range (0 - 5V);
    float voltage0 = val1 * (5.0 / 1023.0);
    // print out the value you read:
    Serial.print(voltage0); Serial.print("i =");
    Serial.print(i); Serial.print(";");
    if (i == 5) Serial.println("  ");
    lcd.setCursor(11, 0);
    lcd.print(voltage0);//reads the current Voltage from A0
  }
  if (!digitalRead(CW))  {
    forward(10);
    all_coils_off();
    lcd.setCursor(13, 3);// set Cursor at place 12, 3
    lcd.print(CW);
  }
  if (!digitalRead(CCW))  {
    reverse(10);
    all_coils_off();
    lcd.setCursor(13, 3);// set Cursor at place 12, 3
    lcd.print(CCW);
  }
  {
    digitalWrite(LED_BUILTIN, HIGH);   // When button is pressed, moves MTR same# of steps as LED timing sequence
    delay(1);                       // wait for a second's
    digitalWrite(LED_BUILTIN, LOW);    //
    delay(1);                       // wait for a second's
  }
  //read the pushbutton value into a variable
  int sensorVal_1 = digitalRead(CW);//SW pin
  //print out the value of the pushbutton
  Serial.println(sensorVal_1);
  // Keep in mind the pullup means the pushbutton's
  // logic is inverted. It goes HIGH when it's open,
  // and LOW when it's pressed. Turn on LED pin when the
  // button's pressed, and off when it's not:
  if (sensorVal_1 == HIGH) {
    digitalWrite(10, LOW);//LED pin
  } else {
    digitalWrite(10, HIGH);//LED pin
  }
  //read the pushbutton value into a variable
  int sensorVal_2 = digitalRead(CCW);//SW pin
  //print out the value of the pushbutton
  Serial.println(sensorVal_2);
  // Keep in mind the pullup means the pushbutton's
  // logic is inverted. It goes HIGH when it's open,
  // and LOW when it's pressed. Turn on LED pin when the
  // button's pressed, and off when it's not:
  if (sensorVal_2 == HIGH) {
    digitalWrite(12, LOW);//LED pin
  } else {
    digitalWrite(12, HIGH);//LED pin
  }
  for (int i = 0; i <= 10; i++)//This keeps LED indicator  on high until button is pressed
  { //then blinks in sync with rotation of motor until released
    (analogRead(A0) / 4 + 10);
  }
  val1 = (analogRead(val1) * 4 + 2); //scale it to use it with the stepper mtr (value between 0 and 175)

} // end loop

void all_coils_off(void) {

  digitalWrite(blue, 0);
  digitalWrite(brown, 0);
  digitalWrite(orange, 0);
  digitalWrite(yellow, 0);

}

void reverse(int i) {

  {
    lcd.setCursor(10, 1);
    lcd.print("<<CCW");
  }
  while (1)   {
    digitalWrite(blue, 1);
    digitalWrite(brown, 0);
    digitalWrite(orange, 1);
    digitalWrite(yellow, 0);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
    digitalWrite(blue, 0);
    digitalWrite(brown, 1);
    digitalWrite(orange, 1);
    digitalWrite(yellow, 0);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(7, 0);
      lcd.print(analogRead(i--) / 4 + 10);
    }
    digitalWrite(blue, 0);
    digitalWrite(brown, 1);
    digitalWrite(orange, 0);
    digitalWrite(yellow, 1);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
    digitalWrite(blue, 1);
    digitalWrite(brown, 0);
    digitalWrite(orange, 0);
    digitalWrite(yellow, 1);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
  }

}

void forward(int i) {

  {
    lcd.setCursor(10, 1);
    lcd.print("CW>>>");
  }
  while (1)   {
    digitalWrite(blue, 1);
    digitalWrite(brown, 0);
    digitalWrite(orange, 0);
    digitalWrite(yellow, 1);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
    digitalWrite(blue, 0);
    digitalWrite(brown, 1);
    digitalWrite(orange, 0);
    digitalWrite(yellow, 1);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
    digitalWrite(blue, 0);
    digitalWrite(brown, 1);
    digitalWrite(orange, 1);
    digitalWrite(yellow, 0);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
    digitalWrite(blue, 1);
    digitalWrite(brown, 0);
    digitalWrite(orange, 1);
    digitalWrite(yellow, 0);
    delay(analogRead(A0) / 4 + 10);
    i--;
    if (i < 1) break;
    {
      lcd.setCursor(12, 2);//print out the value of the pushbutton
      lcd.print(i--);
    }
  }

}

This is the Code for running the TCD1304DG 16 Bit ADC for the CCD detector Project

#include <util/delay_basic.h>

#define RD (1<<2)
#define CNVST (1<<3)
#define BYTESWAP (1<<4)
#define ICG (1<<5)
#define SH (1<<6)
#define MCLK (1<<7)

// Full frame, including dark pixels
// and dead pixels.
#define PIXEL_COUNT 3691

// Ports and pins
#define CLOCKS PORTD
#define CLOCKP PIND
#define CLOCKS_DDR DDRD
#define DATA_PINS PINC
#define DATA_PORT PORTC
#define DATA_DDR DDRC

// 10mS exposure time.
#define EXPOSURE_TIME 10

// Initial clock state.
uint8_t clocks0 = (RD + CNVST + ICG);

// 16-bit pixel buffer
uint16_t pixBuf[PIXEL_COUNT];

char cmdBuffer[16];
int cmdIndex;
int exposureTime = EXPOSURE_TIME;
int cmdRecvd = 0;

/*
* readLine() Reads all pixels into a buffer.
*/

void readLine() {
// Get an 8-bit pointer to the 16-bit buffer.
uint8_t *buf = (uint8_t *) pixBuf;
int x = 0;
uint8_t scratch = 0;

// Disable interrupts or the timer will get us.
cli();

// Synchronize with MCLK and
// set ICG low and SH high.
scratch = CLOCKS;
scratch &= ~ICG;
scratch |= SH;
while(!(CLOCKP & MCLK));
while((CLOCKP & MCLK));
TCNT2 = 0;
_delay_loop_1(1);
__asm__(“nop”);
__asm__(“nop”);
__asm__(“nop”);
__asm__(“nop”);
__asm__(“nop”);
CLOCKS = scratch;

// Wait the remainder of 4uS @ 20MHz.
_delay_loop_1(22);
__asm__(“nop”);
__asm__(“nop”);

// Set SH low.
CLOCKS ^= SH;

// Wait the reaminder of 4uS.
_delay_loop_1(23);

// Start the readout loop at the first pixel.
CLOCKS |= (RD + CNVST + ICG + BYTESWAP + SH);
__asm__(“nop”);

do {
// Wait a minimum of 250nS for acquisition.
_delay_loop_1(2);

// Start the conversion.
CLOCKS &= ~CNVST;
CLOCKS |= CNVST;

// Wait a minimum of 1uS for conversion.
_delay_loop_1(4);

// Read the low byte of the result.
CLOCKS &= ~RD;
_delay_loop_1(4);

*buf++ = DATA_PINS;

// Setup and read the high byte.
CLOCKS &= ~(BYTESWAP);
_delay_loop_1(4);

*buf++ = DATA_PINS;

// Set the clocks back to idle state
CLOCKS |= (RD + BYTESWAP);

// Toggle SH for the next pixel.
CLOCKS ^= SH;

} while (++x < PIXEL_COUNT);

sei();
}

/*
* clearLine() Clears the CCD.
*/

void clearLine() {

int x = 0;

// Set ICG low.
CLOCKS &= ~ICG;
CLOCKS |= SH;
_delay_loop_1(14);

// Set SH low.
CLOCKS ^= SH;
_delay_loop_1(10);

// Reset the timer so the edges line up.
TCNT2 = 0;

CLOCKS |= (RD + CNVST + ICG + BYTESWAP + MCLK);

do {
CLOCKS ^= SH;
_delay_loop_1(10);

} while (++x < PIXEL_COUNT);

}

/*
* sendLine() Send the line of pixels to the user.
*/
void sendLine() {
uint16_t x;

for (x = 0; x < PIXEL_COUNT; ++x) {
Serial.print(x);
Serial.print(“,”);
Serial.print(pixBuf[x]);
Serial.print(“\n”);
}
}

/*
* setup()
* Set the data port to input.
* Set the clock port to output.
* Start timer2 generating the Mclk signal
*/

void setup() {
DDRB |= 0x01;
PORTB &= ~1;
delay(10);
CLOCKS_DDR = 0xff;
CLOCKS = 0; //clocks0;
DATA_DDR = 0x0;
Serial.begin(115200);
PORTB |= 0x01;
// Setup timer2 to generate an 888kHz frequency on D10
TCCR2A = (0 << COM2A1) | (1 << COM2A0) | (1 << WGM21) | (0 << WGM20);
TCCR2B = (0 << WGM22) | (1 << CS20); OCR2A = 8; TCNT2 = 0; delay(10); } /* * loop() * Read the CCD continuously. * Upload to user on switch press. */ void loop() { int x; char ch; // If we got a command last time, execute it now. if (cmdRecvd) { if (cmdBuffer[0] == ‘r’) { // Send the readout to the host. sendLine(); } else if (cmdBuffer[0] == ‘e’) { delay(10); Serial.write(cmdBuffer); // Set the exposure time. sscanf(cmdBuffer + 1, “%d”, &exposureTime); if (exposureTime > 1000) exposureTime = 1000;
if (exposureTime < 1) exposureTime = 1;
}

// Get ready for the next command.
memset(cmdBuffer, 0, sizeof(cmdBuffer));
cmdIndex = 0;
cmdRecvd = 0;
}
// Clear the CCD.
clearLine();

// Integrate.
delay(exposureTime);

// Read it for real.
readLine();

// See if the host is talking to us.
if (Serial.available()) {
ch = Serial.read();

// If char is linefeed, it is end of command.
if (ch == 0x0a) {
cmdBuffer[cmdIndex++] = ‘\0’;
cmdRecvd = 1;

// Otherwise it is a command character.
} else {
cmdBuffer[cmdIndex++] = ch;
cmdRecvd = 0;
}
}
}

This is the Fast 8 Bit code for the TCD1304DG CCD detector utilizing the ADC0820CCN/NOPB

#include <util/delay_basic.h>

// Debug point pin 16
#define DBG 0x04

// ADC RD signal pin 17
#define RD 0x08

// ADC write signal pin 18
#define WR 0x10

// CCD Shift Gate pin 19
#define SH 0x20

// CCD Integration Clear Gate pin 20
#define ICG 0x40

// CCD Master clock pin 21
#define MCLK 0x80

// CCD and ADC clocks
#define CLOCK PORTD

// ADC data
#define ADATA PINC

uint8_t buffer[3694];
char cmdBuffer[16];
int cmdIndex;
int exposureTime = 10;

void setup()
{
// Initialize the clocks.
DDRD |= (WR | SH | ICG | MCLK | RD | DBG); // Set the clock lines to outputs
CLOCK |= ICG; // Set the integration clear gate high.
CLOCK |= (RD | WR); // Set the ADC wr line high.

// Setup the ADC data port.
DDRC = 0;
// Enable the serial port.
Serial.begin(115200);

// Setup timer2 to generate a 470kHz frequency on pin 21
TCCR2A = + (0 << COM2A1) | (1 << COM2A0) | (1 << WGM21) | (0 << WGM20);
TCCR2B = (0 << WGM22) | (1 << CS20);
OCR2A = 16;
TCNT2 = 1;
}

void readCCD(void)
{
int x;
uint8_t dummy;

// Clear the CCD shift register and
// dump the electrons into it.
CLOCK |= DBG;
CLOCK &= ~ICG;
_delay_loop_1(12);
CLOCK |= SH;
delayMicroseconds(5);
CLOCK &= ~SH;
delayMicroseconds(10);
CLOCK |= ICG;
delayMicroseconds(1);

for (x = 0; x < 3694; x++)
{
// Shift out one pixel and
// digitize it.
CLOCK |= SH;

// ADC write.
CLOCK &= ~WR;
delayMicroseconds(1);
CLOCK |= WR;

// ADC convert.
delayMicroseconds(2);

// ADC read.
CLOCK &= ~RD;
delayMicroseconds(1);
buffer[x] = ADATA;
CLOCK |= RD;

// Eat up a few cycles for timing.
asm(“nop”);
asm(“nop”);
asm(“nop”);
asm(“nop”);

CLOCK &= ~SH;
delayMicroseconds(4);
}
CLOCK &= ~DBG;
}

void sendData(void)
{
int x;

for (x = 30; x < 3678; ++x) { Serial.print(x – 30); Serial.print(“,”); Serial.print(buffer[x]); Serial.print(“\n”); } } int cmdRecvd = 0; void loop() { int x; char ch; if (cmdRecvd) { if (cmdBuffer[0] == ‘r’) { sendData(); } else if (cmdBuffer[0] == ‘e’) { sscanf(cmdBuffer+1,”%d”, &exposureTime); if (exposureTime > 1000) exposureTime = 1000;
}
memset(cmdBuffer, 0, sizeof(cmdBuffer));
cmdIndex = 0;
cmdRecvd = 0;
}
delay(exposureTime);
readCCD();
if (Serial.available())
{
ch = Serial.read();
if (ch == 0x0a) {
cmdBuffer[cmdIndex++] = ‘\0’;
cmdRecvd = 1;
} else {
cmdBuffer[cmdIndex++] = ch;
cmdRecvd = 0;
}
}
}

V3.01 Turret Grating Control Firmaware (REV B)

#include #include

/* Program 1

Stepper motor demo for the 28YBJ-48 (stepper MTR) and ULN2003 driver
This particular stepper motor is 5.625 degrees per step
/64

Speed is controlled by a delay between each step.
The longer the delay the slower the rotation.
That delay value is obtained by reading and analog-to-digital
cover (A0 in this case/10K trimmer POT) which gives a value from 0 to 1023.
The value is divided by 4 and add 10 for a delay
in milliseconds:delay(analogRead(0)/4 +10)
For faster speeds change 10 to say 2.
This is calculated between every step to vary speed while stepping.

The commands below will be compiled into machine code and uploaded
to the microcontroller.

Compiled size 1896 bytes.

*/

#define yellow 7 // M1
#define orange 5 // M2
#define brown 6 // M3
#define black 4 // M4

#define CW 2 //Sw1 in schematic
#define CCW 3 //Sw2 in schematic

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address

void setup() {

pinMode(CW, INPUT);
pinMode(CCW, INPUT);

digitalWrite(CW, 1); // pull up on
digitalWrite(CCW, 1); // pull up on

pinMode(black, OUTPUT);
pinMode(brown, OUTPUT);
pinMode(orange, OUTPUT);
pinMode(yellow, OUTPUT);

// all coils off
digitalWrite(black, 0);
digitalWrite(brown, 0);
digitalWrite(orange, 0);
digitalWrite(yellow, 0);

lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight

// ——- Quick 3 blinks of backlight ————-
for (int i = 0; i < 3; i++)
{
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(250);
}
lcd.backlight(); // finish with backlight on
// set up the LCD’s number of columns and rows:
lcd.begin(20, 4);
// Print a message to the LCD.
lcd.print(“AN/MAP:”);

lcd.setCursor(12, 0);

lcd.print(“0-1023”);

lcd.setCursor(0, 1);
lcd.print(“Direction:”);//CCW or CC

lcd.setCursor(0, 2);
lcd.print(“V3.01 Turret Control”);//4th line for version display

Serial.begin(115200);

}

void loop() {

if (!digitalRead(CW)) {

forward(10);
all_coils_off();
}

if (!digitalRead(CCW)) {

reverse(10);
all_coils_off();
}

} // end loop

void all_coils_off(void) {

digitalWrite(black, 0);
digitalWrite(brown, 0);
digitalWrite(orange, 0);
digitalWrite(yellow, 0);

}

void reverse(int i) {
{
lcd.setCursor(10, 1);
lcd.print(“<<CCW”);
}
while (1) {

digitalWrite(black, 1);
digitalWrite(brown, 0);
digitalWrite(orange, 1);
digitalWrite(yellow, 0);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;

digitalWrite(black, 0);
digitalWrite(brown, 1);
digitalWrite(orange, 1);
digitalWrite(yellow, 0);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;
{
lcd.setCursor(7, 0);
lcd.print(analogRead(0) / 4 + 2);
}
digitalWrite(black, 0);
digitalWrite(brown, 1);
digitalWrite(orange, 0);
digitalWrite(yellow, 1);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;

digitalWrite(black, 1);
digitalWrite(brown, 0);
digitalWrite(orange, 0);
digitalWrite(yellow, 1);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break; } }   void forward(int i) { { lcd.setCursor(10, 1); lcd.print(“CW>>>”);
}
while (1) {

digitalWrite(black, 1);
digitalWrite(brown, 0);
digitalWrite(orange, 0);
digitalWrite(yellow, 1);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;

digitalWrite(black, 0);
digitalWrite(brown, 1);
digitalWrite(orange, 0);
digitalWrite(yellow, 1);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;

digitalWrite(black, 0);
digitalWrite(brown, 1);
digitalWrite(orange, 1);
digitalWrite(yellow, 0);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;

digitalWrite(black, 1);
digitalWrite(brown, 0);
digitalWrite(orange, 1);
digitalWrite(yellow, 0);
delay(analogRead(0) / 4 + 2);
i–;
if (i < 1) break;
}
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s