Go Down

Topic: HDD clock code stops halfway (Read 960 times) previous topic - next topic



I've been making a HDD clock, but when putting my, independantly working, code pieces together something broke.


It gets to the point  Serial.println("IO is set");

but then it stops. When removing the lines Cli(); and Sei(); it get's to the point of Serial.println("Servo is set");

What am I overlooking? I tried putting as many needed comments next to the code, and hope it's clear enough to find a possible solution.

Thanks In advance.


My company blocks paste bin. Why didn't you simply attach the code?
The art of getting good answers lies in asking good questions.


Code: [Select]

//___________________ Librairies & defines __________________//
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <stdio.h>
//RTC libs
#include <Wire.h>
#include <RTClib.h>

#ifndef F_CPU
#define F_CPU           16000000UL  // 16 MHz

// frequencion division
#define FREQ_DIV_8      (F_CPU / 8)
// #of ticks / millisec
#define MILLITICK       (FREQ_DIV_8 * .001)

//______________________ Constants and global variables_______________//
const int  divisions = 180;  //a multiple of 60 to simplyfy the positioning

volatile byte LED [divisions+1]; //Array with positions where the leds should light up. in bytes so we can clock it directly in the portB register

// _____________period of the rotation of the disk
int period;
// ______________volatile so it will be accessible in the IRS routine
volatile int positionCounter = 0;

//____________RTC declareren

volatile boolean update; //variable to trigger update

void setup()

  Serial.println("serial is set");
  //______________ RTC opzetten_____________//
// Wire.begin();

  Serial.println("rtc is set");
  //________________    Set I/O ports   ______________//

  DDRL=255 ;   //PL4 pin 45 as output for servo
  DDRB=255;      // pin 51 - 52 - 53 as ooutput for portb
  Serial.println("IO is set");
  //___________________Init Timers_______________________//
cli(); //disable timers

  //**********          PWM for Servo (ESC)     ****************//

  TCCR5A = (1 << COM5B1); // timer5: phase & frequency correct - pwm Clear OC1B on Compare Match
  TCCR5B = (1 << WGM53)  | (1 << CS51); //prescaler 8

  ICR5 = 20000; // 20ms
  OCR5B= 1500; // 1.5ms
  Serial.println("servo is set");
  //***************      Timers for disk position     *****************//

  // setup timer0 - 8bit, --> to drive the leds
  TCCR2A = 0;
  TCCR2B = 0;
  // select CTC mode:  clear timer on compare match mode
  TCCR2A = (1<< WGM21);
  // select prescaler clk / 8
  TCCR2B= (1<< CS21);
  // enable compare interrupt
  TIMSK2 = (1<<OCIE2A);

  // setup timer1 - 16bit to count the rotations and calculate the period
  TCCR3B = 0;
  TCCR3A = 0; // A1 registering p134
  // select prescaler clk / 8
  TCCR3B=(1<< CS31);
  // reset timer
  TCNT3 = 0;
  // enable overflow interrupt
  TIMSK3=(1<< TOIE3);
  Serial.println("timer1 is set");
  // stel PIN2( arduino D-input) falling edge interrupt
  EICRA |= _BV(ISC21); 
  EIMSK |= _BV(INT2);
  Serial.println("int2 is set");
  // set the rotational period to 0

  period = 0;

  // setup timer3 - 16bit, --> to drive time keeping function
  TCCR4A = 0;
  TCCR4B = 0;
  // select CTC mode:  clear timer on compare match mode
  TCCR4A = (1<< WGM41);
  // select prescaler clk / 1024
  TCCR4B= (1<< CS40)|(1<<CS42);
  // enable compare interrupt
  TIMSK4 = (1<<OCIE4A);

  OCR4A=6250; //400ms
  Serial.println("timer4 is set");
sei(); //reenable interrupts
Serial.println("timers are set");

  for(int i =0; i<divisions;i++){  //Set all bytes in the array to zero
  Serial.println("array is empty");
  //Getting out of settings mode of the ESC & Testing leds
  OCR5B = 2000;
  OCR5B = 1000;
  OCR5B = 2000;

void loop()

      DateTime now = RTC.now();
      int hours=now.hour()%12; //getting the time from 0 to 11 instead of 24 hours
      int minutes= now.minute();
      int seconds= now.second();

      for(int i =0; i<divisions;i++){  //clear the whole array
        LED[hours*15] |= 4;
        LED[minutes*3] |= 2;
        LED[seconds*3] |= 1;



ISR(INT2_vect)   //Sensor interrupt routine
  // period = nuber of ticks since last interrupt
  period = TCNT3;
  // if period < than to millis no rotation is possible --> discard value
  // disk 7500 rpm --> 125rps -->8 millis /rotation
  if(period <(2 * MILLITICK)) 
  //reset timer to zero
  TCNT3 = 0;
  //8bit timer0 generates an interrupt / division --> time between interrupts = period/divisions
  TCNT2 = 0; 
  OCR2A = (period / divisions);
  positionCounter = 25;  // set position to 25. sensor is rotated 37° to the length axis of the disk.

ISR(TIMER2_COMPA_vect) { //timer interrupt routine
  positionCounter = ((positionCounter + 1) % divisions); //position with modulo division
  PORTB=LED[positionCounter]; //getting the led values of the current position and clocking them in the portB output register.

ISR(TIMER4_COMPA_vect) { //timer interrupt routine
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.


Code: [Select]
cli(); //disable timers
I always advise a little research before using a function. cli() does FAR more than disable timers. It stopps all interrupts. You can't do things that require interrupts while you have interrupts disabled. That means NO Serail.print() calls between cli() and sei().

The art of getting good answers lies in asking good questions.


I know. But wouldn't it resume everything else after sei(); ?


I know. But wouldn't it resume everything else after sei(); ?

You are assuming that it gets there. If the serial buffer gets full, Serial.print() blocks until there is room in the buffer. Making room in the buffer requires shifting data out, which requires interrupts, which you have disabled.
The art of getting good answers lies in asking good questions.


Also, doesn't delay() require millis(), and isn't millis() run from a timer interrupt ...?

Go Up