Go Down

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

Hi,

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

http://pastebin.com/Rc1rp9mf

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.

PaulS

My company blocks paste bin. Why didn't you simply attach the code?

AWOL

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
#endif


// 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
RTC_DS1307 RTC;

volatile boolean update; //variable to trigger update

void setup()
{

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

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

  DDRL=255 ;   //PL4 pin 45 as output for servo
  DDRB=255;      // pin 51 - 52 - 53 as ooutput for portb
  DDRD=0;
  Serial.println("IO is set");
delay(50);
  //___________________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");
  delay(50);
  //***************      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");
  delay(50);
  // stel PIN2( arduino D-input) falling edge interrupt
  EICRA |= _BV(ISC21); 
  EIMSK |= _BV(INT2);
  Serial.println("int2 is set");
  delay(50);
  // 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");
  delay(50);
sei(); //reenable interrupts
  Serial.begin(9600);
Serial.println("timers are set");
delay(50);


  for(int i =0; i<divisions;i++){  //Set all bytes in the array to zero
    LED[positionCounter]=0;
  }
  Serial.println("array is empty");
  //Getting out of settings mode of the ESC & Testing leds
  PORTB=0b00000001;
  _delay_ms(5000);
  PORTB=0b00000010;
  OCR5B = 2000;
  _delay_ms(2000);
  PORTB=0b00000100;
  OCR5B = 1000;
  _delay_ms(2000);
  OCR5B = 2000;
  PORTB=0b00000000;



}
void loop()
  {

   
    if(update){
      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[positionCounter]=0;
      }
        LED[hours*15] |= 4;
        LED[minutes*3] |= 2;
        LED[seconds*3] |= 1;

      }
      update=false;
   

  }



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)) 
  {
    return;
  }
  //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
update=true;
}
"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.

PaulS

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().


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

PaulS

Quote
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.

majenko

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

Go Up