y2kbug icon

waveclock

y2kbug | PRO | 12/04/15 01:03:22 PM UTC | 0 ⭐ | 840 👁️ | Never ⏰ | []
C |

6.37 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bcm2835.h>
#include <signal.h>
#include <time.h>
 
#define PIN RPI_V2_GPIO_P1_07
 
void gen_pulse(int ms)
{
    int len = ms * 40 + 1;
    while (len--)
    {
        bcm2835_gpio_write(PIN, HIGH);
        bcm2835_delayMicroseconds(12);
        bcm2835_gpio_write(PIN, LOW);
        bcm2835_delayMicroseconds(12);
    }
}
 
void transmit_timecode(int *send_data)
{
    int i;
    
    for( i = 0; i < 60; i++ ) {
        switch( send_data[i] ) {
            
            case -1:    // マーカー
                gen_pulse(200);
                bcm2835_delayMicroseconds(800 * 1000);
                break;
            
            case 1:     // 1
                gen_pulse(500);
                bcm2835_delayMicroseconds(500 * 1000);
                break;
            
            case 0:
                gen_pulse(800);
                bcm2835_delayMicroseconds(200 * 1000);
                break;
        }
    }
}
 
 
void wait_for_next_minute()
{
    struct timeval tv;
    time_t jt;
    struct tm *tmt;
    suseconds_t usec;
    
    gettimeofday(&tv,NULL);
    usec = (suseconds_t)1000000 - (tv.tv_usec % 1000000);
    fprintf(stdout , "wait for next second, %u usec\n",  usec );
    usleep(usec);
    
    jt = time(NULL);
    tmt = localtime(&jt);
    usec = (60 - tmt->tm_sec) * 1000 * 1000;
    fprintf(stdout , "wait for next minute, %u usec\n",  usec );
    usleep(usec);
}
 
void signal_handler(int sig)
{
    bcm2835_gpio_write(PIN, LOW);
    exit(0);
}
 
int main(int argc, char *argv[])
{
    int i;
    int f_daemon = 0;
    
    if( bcm2835_init() < 0 ) {
        fprintf( stderr, "could not initialize bcm2835\n" );
    }
    
    bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
    
    /* options */
    if( argc > 1 ) {
        for( i = 1; i < argc; i++ ) {
            char *param = argv[i];
            
            if( strcmp( param, "-d" ) == 0 ) f_daemon = 1;
            else if( strcmp( param, "-h" ) == 0 ) {
                fprintf( stderr, "Usage %s [OPTION]\n"
                                 "OPTIONS are follows\n"
                                 "  -d   daemonize\n"
                                 "  -h   display this text and exit\n", argv[0] );
                exit(0);
            }
        }
    }
    
    /* signal handle */
    signal( SIGKILL, signal_handler );
    signal( SIGTERM, signal_handler );
    signal( SIGINT, signal_handler );
    
    if( f_daemon ) daemon( 0, 0 );
    
    while (1) {
        int t;
        time_t jt;
        struct tm *tmt;
        int send_data[60];
        
        wait_for_next_minute();
        
        jt = time(NULL);
        tmt = localtime(&jt);
        fprintf(stdout, "Current time: %04d/%02d/%02d %02d:%02d:%02d\n",
                         tmt->tm_year + 1900, tmt->tm_mon+1, tmt->tm_mday,
                         tmt->tm_hour, tmt->tm_min, tmt->tm_sec);
 
        // マーカー
        send_data[0] = -1;
        
        // 分の10の位
        t = tmt->tm_min / 10;
        send_data[1] = t & 4 ? 1 : 0;
        send_data[2] = t & 2 ? 1 : 0;
        send_data[3] = t & 1 ? 1 : 0;
        send_data[4] = 0;
        
        // 分の1の位
        t = tmt->tm_min - t * 10;
        send_data[5] = t & 8 ? 1 : 0;
        send_data[6] = t & 4 ? 1 : 0;
        send_data[7] = t & 2 ? 1 : 0;
        send_data[8] = t & 1 ? 1 : 0;
    
        // マーカー
        send_data[9] = -1;
        send_data[10] = 0;
        send_data[11] = 0;
        
        // 時の10の位
        t = tmt->tm_hour / 10;
        send_data[12] = t & 2 ? 1 : 0;
        send_data[13] = t & 1 ? 1 : 0;
        
        send_data[14] = 0;
 
        // 時の1の位
        t = tmt->tm_hour - t * 10;
        send_data[15] = t & 8 ? 1 : 0;
        send_data[16] = t & 4 ? 1 : 0;
        send_data[17] = t & 2 ? 1 : 0;
        send_data[18] = t & 1 ? 1 : 0;
    
        // マーカー
        send_data[19] = -1;
        
        send_data[20] = 0;
        send_data[21] = 0;
        
        // 1月1日の経過年100の位
        t = (tmt->tm_yday + 1) / 100;
        send_data[22] = t & 2 ? 1 : 0;
        send_data[23] = t & 1 ? 1 : 0;
    
        send_data[24] = 0;
    
        // 1月1日の経過年10の位
        t = (tmt->tm_yday + 1) / 10 - t * 10;
        send_data[25] = t & 8 ? 1 : 0;
        send_data[26] = t & 4 ? 1 : 0;
        send_data[27] = t & 2 ? 1 : 0;
        send_data[28] = t & 1 ? 1 : 0;
    
        // マーカー
        send_data[29] = -1;
    
        // 1月1日の経過年1の位
        t = (tmt->tm_yday + 1) % 100 - t * 10;
        send_data[30] = t & 8 ? 1 : 0;
        send_data[31] = t & 4 ? 1 : 0;
        send_data[32] = t & 2 ? 1 : 0;
        send_data[33] = t & 1 ? 1 : 0;
 
        send_data[34] = 0;
        send_data[35] = 0;
        
        // チェックサム
        t = 0;
        for(i = 12 ;i < 19 ; i++) {
            t += send_data[i] == 1 ? 1 : 0;
        }
        send_data[36]= t & 1;
        
        // チェックサム
        t = 0;
        for (i = 1 ; i < 9 ; i++) {
            t += send_data[i] == 1 ? 1 : 0;
        }
        send_data[37]= t & 1;
    
        send_data[38] = 0;
        
        // マーカー
        send_data[39] = -1;
        send_data[40] = 0;
    
        // 年の10の位
        t = (tmt->tm_year % 100) / 10;
        send_data[41]= t & 8 ? 1 : 0;
        send_data[42]= t & 4 ? 1 : 0;
        send_data[43]= t & 2 ? 1 : 0;
        send_data[44]= t & 1 ? 1 : 0;
        
        // 年の1の位
        t = (tmt->tm_year % 100 ) - t * 10;
        send_data[45] = t & 8 ? 1 : 0;
        send_data[46] = t & 4 ? 1 : 0;
        send_data[47] = t & 2 ? 1 : 0;
        send_data[48] = t & 1 ? 1 : 0;
        
        // マーカー
        send_data[49] = -1;
 
        // 週(曜日)
        t = tmt->tm_wday;
        send_data[50] = t & 4 ? 1 : 0;
        send_data[51] = t & 2 ? 1 : 0;
        send_data[52] = t & 1 ? 1 : 0;
        
        send_data[53] = 0;
        send_data[54] = 0;
        
        send_data[55] = 0;
        send_data[56] = 0;
        send_data[57] = 0;
        send_data[58] = 0;
        
        // マーカー
        send_data[59] = -1;
    
        transmit_timecode(send_data);
    }
}

Comments