Skip to content

Instantly share code, notes, and snippets.

@ak1211

ak1211/irsend.c

Created Jan 2, 2020
Embed
What would you like to do?
irsend プログラム(C言語とpigpioデーモンライブラリ)
/*
irremocon <https://github.com/ak1211/irremocon>
Copyright 2019 Akihiro Yamamoto
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//
// use pigpiod daemon
//
// install libraries
// sudo apt-get install pigpio
//
// build
//
// $ gcc -Wall -pthread -o irsend irsend.c -lpigpiod_if2 -lrt
#include <assert.h>
#include <stdbool.h>
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <pigpiod_if2.h>
// キャリア周波数[kHz}
// 38kHz
const uint16_t CARRIER_FREQ_KHZ = 38;
// キャリア周期[us]
// 1/38,000 * 1,000,000 = 26us
const uint16_t CARRIER_PERIOD_MICROS = 1000 / CARRIER_FREQ_KHZ;
// 1/3 duty cycle
const uint16_t ON_DUTY_MICROS = CARRIER_PERIOD_MICROS / 3;
///
/// リモコン信号送信
///
void transmit_ir_codes( int pi, uint16_t* ircodes, size_t ircodes_size )
{
int tfd = timerfd_create( CLOCK_REALTIME, 0 );
uint64_t v;
struct itimerspec timer = {
.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
.it_value = { .tv_sec = 0, .tv_nsec = 0 }
};
for(int i=0 ; i<ircodes_size/2 ; i+=2 ) {
uint16_t ton = ircodes[i];
uint16_t toff = ircodes[i+1];
timer.it_value.tv_nsec = 26 * ton * 1000;
timerfd_settime( tfd, 0, &timer, NULL );
//
// 赤外線LED出力ピン (GPIO 18 / Physical 12)
hardware_PWM( pi, 18, 38000, 1000000/3 );
// タイマー待ち
if (read( tfd, &v, sizeof(uint64_t) ) < 0) {
goto exit;
}
//
timer.it_value.tv_nsec = 26 * toff * 1000;
timerfd_settime( tfd, 0, &timer, NULL );
//
// 赤外線LED出力ピン (GPIO 18 / Physical 12)
hardware_PWM( pi, 18, 0, 0 );
// タイマー待ち
if (read( tfd, &v, sizeof(uint64_t) ) < 0) {
goto exit;
}
}
exit:
hardware_PWM( pi, 18, 0, 0 );
}
//
//
//
int main()
{
int pi;
if ((pi = pigpio_start( NULL, NULL )) < 0) {
perror("");
return 0;
}
fprintf( stderr, "irsend\n" );
enum { LINE_BUFFER_SIZE = 1024 };
char line_buffer[LINE_BUFFER_SIZE ];
if (fgets( line_buffer, LINE_BUFFER_SIZE, stdin ) == NULL) {
goto exit;
}
char* p;
if ((p = strrchr( line_buffer, '\n' )) != NULL) {
*p = '\0';
}
if (strlen(line_buffer) % 4 != 0) {
perror("bad length.");
goto exit;
}
for (p=line_buffer ; *p != '\0' ; p++) {
if (!isxdigit(*p)) {
perror("bad inputs.");
goto exit;
}
}
enum { IRCODES_SIZE = 1024 };
uint16_t ircodes[IRCODES_SIZE] = {0};
size_t count = 0;
for (size_t i=0 ; i<strlen(line_buffer) ; i+=4) {
char work[3] = "";
unsigned int lo, hi;
strncpy( work, &line_buffer[i], 2);
sscanf( work, "%x", &lo );
strncpy( work, &line_buffer[i+2], 2);
sscanf( work, "%x", &hi );
ircodes[count++] = hi << 8 | lo ;
}
for( ssize_t c=0 ; c<count ; c++ ) {
int lo =ircodes[c] & 0x00ff;
int hi =ircodes[c] >> 8 & 0x00ff;
printf( "%02X%02X", lo, hi );
}
printf( "\n" );
transmit_ir_codes( pi, ircodes, count );
fprintf( stderr, "bye.\n");
exit:
pigpio_stop(pi);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.