Pages: [1]   Go Down
Author Topic: HDD clock code stops halfway  (Read 452 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45973
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24284
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:

//___________________ 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;
}
Logged

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

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45973
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 19
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45973
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Pages: [1]   Go Up
Jump to: