[C言語]TCP/IP

サーバ側

#include 
#include 
#include 
#include 

int main(int argc, char** argv){
	int sd;
	int acc_sd;
	struct sockaddr_in addr;

	socklen_t sin_size = sizeof(struct sockaddr_in);
	struct sock_in from addr;

	char buf[2048];

	memset(buf, 0, sizeof(buf));

	if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		perror("socket");
		return -1;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(22222);
	addr.sin_addr.s_addr = INADDR_ANY;

	if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0){
		perror("bind");
		return -1;
	}

	if(listen(sd, 10) < 0){
		perror("listen");
		return -1;
	}

	if((acc_sd) = accept(sd, (struct sockaddr *)&from_addr, &sin_size)) < 0 {
		perror("accept");
		return -1;
	}

	if(recv(acc_sc, buf, sizeof(buf), 0) < 0){
		perror("recv");
		return -1;
	}

	close(acc_sd);

	close(sd);

	printf("%s\n", buf);

	return 0;

}

client

#include 
#include 
#include 

int main(int argc, char** argv){
	int sd;
	struct sockaddr_in addr;

	if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		perror("socket");
		return -1;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(22222);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");

	connect(sd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));

	if(send(sd, "sending process", 17, 0) < 0){
		perror("send");
		return -1;
	}

	close(sd);

	return 0;
}

[C言語]バイナリファイル

パケットフィルタリングとは、通信機器やコンピュータの持つネットワーク制御機能の一つで、外部から受信したデータを管理者が設定した一定の基準に従って通したり破棄したりすること
Berkeley Packet Filterとは、ユーザランドからのコードをカーネル内で安全に実行する為の仕組み

$ grep BPF /boot/config-`uname -r`
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_TEST_BPF=m

#include 
#include 
#include 
#include 
#include "bpf_load.h"
#include "sock_example.h"
#include 
#include 

int main(int ac, char **argv){

	char filename[256];
	FILE *f;
	int i, sock;

	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);

	if(load_bpf_file(filename)){
		printf("%s", bpf_log_buf);
		return 1;
	}

	sock = open_raw_sock("lo");

	assert(setsockopt(sock, SQL_SOCKET, SO_ATTACH_BPF, prog_fd, sizeof(prog_fd[0])) == 0);

	f = popen("ping -c5 localhost", "r");
	(void) f;

	for(i = 0; i < 5; i++){
		long long tcp_cnt, udp_cnt, icmp_cnt;
		int key;

		key = IPPROTO_TCP;
		assert(bpf_map_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0);

		key = IPPROTO_UDP;
		assert(bpf_map_lookup_elem(map_fd[0], &key, &udp_cnt) == 0);

		key = IPPROTO_ICMP;
		assert(bpf_map_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0);

		printf("TCP %lld UDP %lld ICMP %lld bytes\n", tcp_cnt, udp_cnt, icmp_cnt);
		sleep(1);
	}

	return 0;
}

TCPとはIPと同様にインターネットにおいて標準的に利用されている プロトコル。TCPは、IPの上位プロトコルでトランスポート層で動作する。
ネットワーク層のIPとセッション層以上のプロトコル(HTTP、FTP、Telnetなど)の橋渡しをする

UDPはUser Datagram Protocolの略、アプリケーション同士が最小限の仕組みでデータを送受信するプロトコル、リアルタイム性が重要視される通信で使われる、送信者アドレスの偽装が容易であるためDNSなどを使ったDDoS攻撃で使われることも多い

ICMPはIPプロトコルの「エラー通知」や「制御メッセージ」を転送するためのプロトコル、TCP/IPが実装されたコンピュータ間で通信状態を確認するために使用

[C言語]バイナリファイル

0と1のビットの並びで表現されたファイルをバイナリファイルと呼ぶ。また、そのデータをバイナリデータと呼ぶ。
行を変えるという概念がない。

– エンディアン
2バイト以上あるデータをメモリ上に配置する時に、どのように並べるかというルールのことで、リトルエンディアンとビッグエンディアンがある。
「0x00 0x00 0x003 0x84」(ビッグエンディアン)と「0x84 0x003 0x00 0x00」(リトルエンディアン)
IntelのCPUはリトルエンディアン

#include <stdio.h>

int main(void){
	printf("%X\n", 'x');
	printf("%X\n", 'y');
	printf("%X\n", 'z');
}

– 読み書き
fopen関数に”b”を含む

#include
#include

int main(void){
FILE *fp = fopen(“test.bin”,”rb”);
if(fp == NULL){
fputs(“ファイルオープンに失敗しました。\n”, stderr);
exit(EXIT_FAILURE);
}

int num = 900;
double d = 7.85;
char str[] = “xyzxyz”;

if(fwrite(&num, sizeof(num), 1, fp) < 1){ fputs("1.ファイル書き込みに失敗しました。\n", stderr); exit(EXIT_FAILURE); } if(fwrite(&d, sizeof(d), 1, fp) < 1){ fputs("2.ファイル書き込みに失敗しました。\n", stderr); exit(EXIT_FAILURE); } if(fwrite(str, sizeof(str[0]),sizeof(str),fp) < sizeof(str)){ fputs("3.ファイル書き込みに失敗しました。\n", stderr); exit(EXIT_FAILURE); } if(fclose(fp) == EOF){ fputs("ファイルクローズに失敗しました。\n", stderr); exit(EXIT_FAILURE); } return 0; } [/code] $ ./test 1.ファイル書き込みに失敗しました。

[C言語]データベース

### 作り方
データを構造体配列にして検索で工夫する
データのレコードやデータベースの項目情報は動的メモリ確保されたメモリ領域にリスト構造で保持
そこから検索アルゴリズムでデータを取り出し、必要に応じてソート処理
データの保存・読み込みにはバイナリファイルの取り扱いノウハウが必要

### 必要知識
検索、リスト構造、ソート、ハッシュ、動的メモリ確保、バイナリファイルの取り扱い

### 構造体配列のサンプル

#include <stdio.h>

struct pop_dt {
	char region[20];
	long pop;
};

int main(void){

	struct pop_dt world[7] = {
		{"asia", 3769},
		{"north_america", 498},
		{"south_america", 357},
		{"europe", 725},
		{"africa", 832},
		{"oceania", 31},
		{"nowhere", 0}
	};

	int i;
	for(i=0; world[i].pop != 0; i++){
		printf("%-15s %6d\n", (world+i)->region, (world+i)->pop);
	}

	return 0;
}

$ ./main
asia 3769
north_america 498
south_america 357
europe 725
africa 832
oceania 31

一つの事をやろうとしたら、副次的に色々な事を学ばなければならない。その量がやたら多いように感じるのは実力がないからか。

[C言語]Webサーバー

IPv4とは?
-> データ通信規格。IPアドレスを32ビットのデータとして扱う
バイトストリームとは?
-> バイト単位のデジタルデータのひと続き

#include 
#include  // typedefシンボルおよび構造体のコレクションを定義
#include  // ソケットに使うためのヘッダファイル socket()
#include  // インターネット・プロトコル・ファミリーの定義


int main(void){

	int rsock, wsock;
	struct sockaddr_in addr, client;
	int len;
	int ret;

	// 通信をするためのソケット作成
	rsock = socket(AF_INET, SOCK_STREAM, 0); // AF_INETはIPv4接続、SOCK_STREAMはバイトストリーム

	if(rsock < 0){
		fprintf(stderr, "Error. Cannot make socket\n");
		return -1;
	}

	// socket設定
	addr.sin_family = AF_INET; // IPv4
	addr.sin_port = htons(8080); // 8080ポート
	addr.sin_addr.s_addr = INADDR_ANY;  // アドレス指定なし

	// binding socket
	bind(rsock, (struct sockaddr *)&addr, sizeof(addr));

	if(ret < 0){
		fprintf(stderr, "Error. Cannot bind socket\n");
		return -1;
	} 

	// socketの接続待ち
	listen(rsock, 5);

	// accept TCP connection from client
	len = sizeof(client);
	wsock = accept(rsock, (struct sockaddr *)&client, &len);

	// メッセージ送信
	write(wsock, "HTTP1.1 200 OK", 14);

	// TCPセッション終了
	close(wsock);
	close(rsock);

	return 0;
}

$ gcc -o main main.c
main.c: In function ‘main’:
main.c:43:2: warning: implicit declaration of function ‘write’; did you mean ‘fwrite’? [-Wimplicit-function-declaration]
write(wsock, "HTTP1.1 200 OK", 14);
^~~~~
fwrite
main.c:46:2: warning: implicit declaration of function ‘close’; did you mean ‘pclose’? [-Wimplicit-function-declaration]
close(wsock);
^~~~~
pclose

ソケットで通信していることはわかったが、よくわからん。

[Arduino]センサー等の種類

### Arduinoで使用できるセンサー等の種類
1.LED: ビジュアルアート、広告
1.7セグLED: 数字表現
2.赤外線: Rubyと合わせて赤外線リモコンなど
2.フォトリフレクタ: 物体があるかないかの判定、血流値の計測
3.光センサー(CdSセル):明るさに応じて抵抗値が変わる
4.温度センサー: 気温
5.湿度センサー: 湿度
6:モーター、モータードライバ: 動力系、ラジコン
7:超音波センサー: 物体との距離を計測
8:加速度センサー: 傾き、衝撃、振動
9:電圧スピーカー: 音
10:土壌センサー: 土の渇きを測定する
11.気圧センサー
12.地磁気センサー
13.近接照度センサー
14.カラーセンサー

### その他
1. 衣装の制御ボード: 2012紅白Perfume
2. イーサネットシールド: Webサーバなどネットワーク接続ができるようになる
3. SDカード
4. ソーラーパネル
5. OSC通信
6. WiFiモジュール
7. ステッピングモーター
8. ハンダ付け

なんだこれーーーーーーーーーーーーー
まだまだ絶対にやらなきゃいけない事たくさんあるのに、Arduinoだけでも、一通りマスターするのに1〜2年かかりそうじゃんか。。。🤮🤮🤮
甘く見過ぎてた、マジどうしよ。。 
結論は急がず、数日、よく考えよう。

Arduino UNO、温度センサー、LEDで気温を表示する

温度センサーLM35DZを使用する。0〜100度まで測定可能
温度センサーの+Vs端子にArduino5V, Voutをアナログ端子(A0〜A5)、GNDにGNDを接続する

アナログ端子は、HIGH/LOW間の1.0V、1.6V、2.0V、2.5V、3.1V…の細かい電圧を読み取れる
読み取った0~5Vの電圧は、0〜1023の値として取得できる。
35だった場合、
35/1023 = 0.034
0.034 * 5 = 0.17V
1V = 100℃
0.17 * 100 = 17℃

#define TERMINAL_A 3
#define TERMINAL_B 4
#define TERMINAL_C 5
#define TERMINAL_D 6
#define TERMINAL_F 7
#define TERMINAL_G 8
#define TERMINAL_H 9
#define TACT_SW 10  // 10番ピンをタクトスイッチ
#define DIGIT_1 11
#define DIGIT_10 12
#define DIGIT_100 13
#define DIGIT_1000 14
#define DP 15 // ドット
#define THERMO_IN 16  // A2端子のため16を指定

byte counter = 0;  // Arduinoで使用できる1byteの型
byte state = 0;
byte state_old = 0;
byte buf_num = 0;
int thermo_buf[10];

void led_output(byte num){

  switch(num) {
      case 0:  // 4桁7セグメントではアノードコモンを使用しており、7セグメントLEDの逆
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 1:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 2:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 3:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 4:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 5:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 6:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 7:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 8:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 9:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, HIGH);
      break;

      default:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;  
    }      
}



void setup() {
  // 初期化
  pinMode(TERMINAL_A, OUTPUT);
  pinMode(TERMINAL_B, OUTPUT);
  pinMode(TERMINAL_C, OUTPUT);
  pinMode(TERMINAL_D, OUTPUT);
  pinMode(TERMINAL_F, OUTPUT);
  pinMode(TERMINAL_G, OUTPUT);
  pinMode(TERMINAL_H, OUTPUT);
  pinMode(DP, OUTPUT);

  pinMode(DIGIT_1, OUTPUT);
  pinMode(DIGIT_10, OUTPUT);
  pinMode(DIGIT_100, OUTPUT);
  pinMode(DIGIT_1000, OUTPUT);
  
  pinMode(TACT_SW, INPUT); // タクトスイッチに接続した10番ピンをインプットに設定
  pinMode(THERMO_IN, INPUT); // 16番ピンをINPUT指定

  digitalWrite(DIGIT_1, LOW);
  digitalWrite(DIGIT_10, LOW);
  digitalWrite(DIGIT_100, LOW);
  digitalWrite(DIGIT_1000, LOW);

  led_output(counter);
}

void clear_num(void){
  digitalWrite(TERMINAL_A, HIGH);
  digitalWrite(TERMINAL_B, HIGH);
  digitalWrite(TERMINAL_C, HIGH);
  digitalWrite(TERMINAL_D, HIGH);
  digitalWrite(TERMINAL_F, HIGH);
  digitalWrite(TERMINAL_G, HIGH);
  digitalWrite(TERMINAL_H, HIGH);
  digitalWrite(DP, HIGH);
}

int get_temperature(void){

    float thermo_sens;
    int thermo;
    int thermo_ave = 0;
    byte i;

    thermo_sens = analogRead(THERMO_IN); // センサー値取得
    thermo_sens = ((5*thermo_sens)/1024) * 100; // 温度へ変換
    thermo = thermo_sens * 10;

    thermo_buf[buf_num] = thermo;  // 初期値は0
    buf_num++;
    if(buf_num > 9){
      buf_num = 0;
    }

    for(i = 0; i < 10; i++){
      thermo_ave = thermo_ave + thermo_buf&#91;i&#93;;
    }
    thermo_ave = thermo_ave / 10;

    return thermo_ave;
}

void loop() {

  int num;
  int thermo;
  state = digitalRead(TACT_SW);  // 電流が流れているとHIGH, 流れていないとLOW

  if((state == HIGH) && (state_old == LOW)){
      counter++;
  } else {
  }

  if(counter >= 10000){
    counter = 0;
  }

  thermo = get_temperature();
  num = thermo/ 1000;
  clear_num();
  digitalWrite(DIGIT_1000, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_1000, LOW);

  num = thermo % 1000;
  num = thermo/ 100;
  clear_num();
  digitalWrite(DIGIT_100, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_100, LOW);

  num = thermo % 100;
  num = num/ 10;
  clear_num();
  digitalWrite(DIGIT_10, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_10, LOW);

  num = thermo % 10;
  clear_num();
  digitalWrite(DIGIT_1, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_1, LOW);
  
  state_old = state;

}

配線

あれ、コンパイルして転送したら、突然シリアルポートを読み込まなくなった。
なんだこれ。

一瞬パニクったが、温度センサーの配線が間違っていた模様。表裏をひっくり返して再度実行

mde

出来ました。
Arduinoは中々良い買い物だった。

4桁7セグメントLEDを使う

4桁7セグメントLEDは仕組みとしては、7セグメントLEDと同じ
6、8、9、12番ピンを指定するとそれぞれの桁が表示される
各桁を0.01秒ずつ順番に表示しているが、目視すると同時に表示されているように見える

#define TERMINAL_A 3
#define TERMINAL_B 4
#define TERMINAL_C 5
#define TERMINAL_D 6
#define TERMINAL_F 7
#define TERMINAL_G 8
#define TERMINAL_H 9
#define TACT_SW 10  // 10番ピンをタクトスイッチ
#define DIGIT_1 11
#define DIGIT_10 12
#define DIGIT_100 13
#define DIGIT_1000 14
#define DP 15 // ドット

byte counter = 0;  // Arduinoで使用できる1byteの型
byte state = 0;
byte state_old = 0;

void led_output(byte num){

  switch(num) {
      case 0:  // 4桁7セグメントではアノードコモンを使用しており、7セグメントLEDの逆
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 1:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 2:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 3:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 4:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 5:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 6:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 7:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 8:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 9:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, HIGH);
      break;

      default:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;  
    }      
}



void setup() {
  // 初期化
  pinMode(TERMINAL_A, OUTPUT);
  pinMode(TERMINAL_B, OUTPUT);
  pinMode(TERMINAL_C, OUTPUT);
  pinMode(TERMINAL_D, OUTPUT);
  pinMode(TERMINAL_F, OUTPUT);
  pinMode(TERMINAL_G, OUTPUT);
  pinMode(TERMINAL_H, OUTPUT);
  pinMode(DP, OUTPUT);

  pinMode(DIGIT_1, OUTPUT);
  pinMode(DIGIT_10, OUTPUT);
  pinMode(DIGIT_100, OUTPUT);
  pinMode(DIGIT_1000, OUTPUT);
  
  pinMode(TACT_SW, INPUT); // タクトスイッチに接続した10番ピンをインプットに設定

  digitalWrite(DIGIT_1, LOW);
  digitalWrite(DIGIT_10, LOW);
  digitalWrite(DIGIT_100, LOW);
  digitalWrite(DIGIT_1000, LOW);

  led_output(counter);
}

void clear_num(void){
  digitalWrite(TERMINAL_A, HIGH);
  digitalWrite(TERMINAL_B, HIGH);
  digitalWrite(TERMINAL_C, HIGH);
  digitalWrite(TERMINAL_D, HIGH);
  digitalWrite(TERMINAL_F, HIGH);
  digitalWrite(TERMINAL_G, HIGH);
  digitalWrite(TERMINAL_H, HIGH);
  digitalWrite(DP, HIGH);
}

void loop() {

  int num;
  state = digitalRead(TACT_SW);  // 電流が流れているとHIGH, 流れていないとLOW

  if((state == HIGH) && (state_old == LOW)){
      counter++;
  } else {
  }

  if(counter >= 10000){
    counter = 0;
  }

  num = counter/ 1000;
  clear_num();
  digitalWrite(DIGIT_1000, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_1000, LOW);

  num = counter % 1000;
  num = counter/ 100;
  clear_num();
  digitalWrite(DIGIT_100, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_100, LOW);

  num = counter % 100;
  num = counter/ 10;
  clear_num();
  digitalWrite(DIGIT_10, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_10, LOW);

  num = counter % 10;
  clear_num();
  digitalWrite(DIGIT_1, HIGH);
  delay(1);
  led_output(num);
  delay(5);
  digitalWrite(DIGIT_1, LOW);
  
  state_old = state;

}

配線

実行

dav

あれ、全然意図した動きになってない
配線が違う
4桁7セグメントLEDのピンに合わせて配線を修正します。
また、プログラムのアノードカソードの箇所も修正を加えます。

mde

デジタル時計が何やってるか大体わかった。
なるほどね、ハードウェアとマイコンとプログラムってことか。世界観変わったわ。

Arduino UNOでタクトスイッチのカウンタ

#define TERMINAL_A 3
#define TERMINAL_B 4
#define TERMINAL_C 5
#define TERMINAL_D 6
#define TERMINAL_F 7
#define TERMINAL_G 8
#define TERMINAL_H 9
#define TACT_SW 10  // 10番ピンをタクトスイッチ

byte counter = 0;  // Arduinoで使用できる1byteの型
byte state = 0;
byte state_old = 0;

void led_output(byte num){

  switch(num) {
      case 0:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 1:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 2:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, LOW);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 3:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 4:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, LOW);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 5:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 6:
      digitalWrite(TERMINAL_A, LOW);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 7:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, LOW);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, LOW);
      digitalWrite(TERMINAL_H, LOW);
      break;
      case 8:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;
      case 9:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, HIGH);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, LOW);
      break;

      default:
      digitalWrite(TERMINAL_A, HIGH);
      digitalWrite(TERMINAL_B, HIGH);
      digitalWrite(TERMINAL_C, HIGH);
      digitalWrite(TERMINAL_D, LOW);
      digitalWrite(TERMINAL_F, HIGH);
      digitalWrite(TERMINAL_G, HIGH);
      digitalWrite(TERMINAL_H, HIGH);
      break;  
    }      
}



void setup() {
  // 初期化
  pinMode(TERMINAL_A, OUTPUT);
  pinMode(TERMINAL_B, OUTPUT);
  pinMode(TERMINAL_C, OUTPUT);
  pinMode(TERMINAL_D, OUTPUT);
  pinMode(TERMINAL_F, OUTPUT);
  pinMode(TERMINAL_G, OUTPUT);
  pinMode(TERMINAL_H, OUTPUT);
  pinMode(TACT_SW, INPUT); // タクトスイッチに接続した10番ピンをインプットに設定

  led_output(counter);
}

void loop() {
  state = digitalRead(TACT_SW);  // 電流が流れているとHIGH, 流れていないとLOW

  if((state == HIGH) && (state_old == LOW)){
      counter++;
  } else {
  }

  if(counter >= 10){
    counter = 0;
  }

  led_output(counter);
  state_old = state;

  delay(50);
  
}

配線

実行結果

mde

loopの箇所だが、タクトスイッチから手を離すと、state == LOWとなるので、state_oldもLOWになる。
配線は7セグメントLEDのGRD(-)がブレッドボードで一緒になっているのでややこしく見えるが、タクトスイッチのHIGH LOWは10番ピンで感知している。

Arduinoは触りだけやったら辞めてラズパイに時間使おうと思ってたけど、Arduinoの奥深さが魅力的になってきた。

Arduino UNOで7セグメントLEDを表示させる

7セグメントLEDとは7つに分割されたという意味

dav

カソード(GNDと接続する端子)がコモン(共通)

端子aに5Vを送ると、7セグメントLEDのaが光る
GNDは2箇所あるが、どちらかを繋げば良い
aとfの端子に電流を流すと、a, fが発光し1を表示しているように見える。eはデジマルポインタDP

#define TERMINAL_A 3
#define TERMINAL_B 4
#define TERMINAL_C 5
#define TERMINAL_D 6
#define TERMINAL_F 7
#define TERMINAL_G 8
#define TERMINAL_H 9

void setup() {
  // 初期化
  pinMode(TERMINAL_A, OUTPUT);
  pinMode(TERMINAL_B, OUTPUT);
  pinMode(TERMINAL_C, OUTPUT);
  pinMode(TERMINAL_D, OUTPUT);
  pinMode(TERMINAL_F, OUTPUT);
  pinMode(TERMINAL_G, OUTPUT);
  pinMode(TERMINAL_H, OUTPUT); 
}

void loop() {
  digitalWrite(TERMINAL_A, HIGH);
  digitalWrite(TERMINAL_B, HIGH);
  digitalWrite(TERMINAL_C, LOW);
  digitalWrite(TERMINAL_D, HIGH);
  digitalWrite(TERMINAL_F, LOW);
  digitalWrite(TERMINAL_G, HIGH);
  digitalWrite(TERMINAL_H, HIGH);
}
dav

やべーな、これ
でも面白い