顯示具有 CH552 標籤的文章。 顯示所有文章
顯示具有 CH552 標籤的文章。 顯示所有文章

2024年12月22日 星期日

[8051] 用CH552設計偵測拍掌聲,控制伺服馬達和語音IC(JQ6500)

 電路圖

程式碼:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <Servo.h>
const int analogInPin = 11;  
const int servoPin = 15;
const int ControlPin = 16;
const int SoundPin = 17; 
// 設定時間間隔為 5 分鐘300,000 毫秒
const int INTERVAL = 300000;
int threshold = 60;

int sensorValue = 0;        // value read from the pot

// 上次執行的時間點
unsigned long previousMillis = 0;

void setup() {
  pinMode(analogInPin,INPUT);
  Servo_init();
  pinMode(servoPin, OUTPUT);
  Servo_attach(servoPin);
  pinMode(ControlPin, OUTPUT);
  digitalWrite(ControlPin, HIGH);  // 初始狀態設為 HIGH
  pinMode(SoundPin, OUTPUT);
  digitalWrite(SoundPin, HIGH);  // 初始狀態設為 HIGH
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);

  // 取得目前的時間
  unsigned long currentMillis = millis();

  // 每隔 5 分鐘執行一次
  if (currentMillis - previousMillis >= INTERVAL) {
    previousMillis = currentMillis; // 更新上次執行的時間點

    // 將 P3.6 拉低 1000 毫秒
    digitalWrite(ControlPin, LOW);
    delay(1000);
    digitalWrite(ControlPin, HIGH);
  }

  if (sensorValue>=threshold){
    USBSerial_print(sensorValue);
    USBSerial_print("\n");
    digitalWrite(SoundPin, LOW);
    delay(1000);
    digitalWrite(SoundPin, HIGH);

    Servo_write(servoPin,0);
    delay(1000);
    Servo_write(servoPin,180);
    delay(1000);
    Servo_write(servoPin,90);
    delay(3000);
  }
  delay(2);
}

2024年12月9日 星期一

[8051] 用CH552控制WS2812燈條

 電路圖:


採用範例程式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <WS2812.h>

#define NUM_LEDS 8
#define COLOR_PER_LEDS 3
#define NUM_BYTES (NUM_LEDS*COLOR_PER_LEDS)

#if NUM_BYTES > 255
#error "NUM_BYTES can not be larger than 255."
#endif

__xdata uint8_t ledData[NUM_BYTES];

void setup() {
  pinMode(15, OUTPUT); //Possible to use other pins. 
}

void loop() {

  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    set_pixel_for_GRB_LED(ledData, i, 1, 0, 0); //Choose the color order depending on the LED you use. 
    neopixel_show_P1_5(ledData, NUM_BYTES); //Possible to use other pins. 
    delay(100);
  }
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    set_pixel_for_GRB_LED(ledData, i, 0, 1, 0);
    neopixel_show_P1_5(ledData, NUM_BYTES);
    delay(100);
  }
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    set_pixel_for_GRB_LED(ledData, i, 0, 0, 1);
    neopixel_show_P1_5(ledData, NUM_BYTES);
    delay(100);
  }

}


WS2812.h程式碼:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * Copyright (c) 2020 by Deqing Sun <ds@thinkcreate.us> (c version for CH552
 * port) Touch key library for arduino CH552.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#ifndef _WS2812_H_INCLUDED
#define _WS2812_H_INCLUDED

// clang-format off
#include <Arduino.h>
#include "template/WS2812_pins_header.h"
// clang-format on

#define set_pixel_for_RGB_LED(ADDR, INDEX, R, G, B)                            \
  {                                                                            \
    __xdata uint8_t *ptr = (ADDR) + ((INDEX)*3);                               \
    ptr[0] = (R);                                                              \
    ptr[1] = (G);                                                              \
    ptr[2] = (B);                                                              \
  };
#define set_pixel_for_GRB_LED(ADDR, INDEX, R, G, B)                            \
  {                                                                            \
    __xdata uint8_t *ptr = (ADDR) + ((INDEX)*3);                               \
    ptr[0] = (G);                                                              \
    ptr[1] = (R);                                                              \
    ptr[2] = (B);                                                              \
  };
#define set_pixel_for_RBG_LED(ADDR, INDEX, R, G, B)                            \
  {                                                                            \
    __xdata uint8_t *ptr = (ADDR) + ((INDEX)*3);                               \
    ptr[0] = (R);                                                              \
    ptr[1] = (B);                                                              \
    ptr[2] = (G);                                                              \
  };
#define set_pixel_for_GBR_LED(ADDR, INDEX, R, G, B)                            \
  {                                                                            \
    __xdata uint8_t *ptr = (ADDR) + ((INDEX)*3);                               \
    ptr[0] = (G);                                                              \
    ptr[1] = (B);                                                              \
    ptr[2] = (R);                                                              \
  };
#define set_pixel_for_BRG_LED(ADDR, INDEX, R, G, B)                            \
  {                                                                            \
    __xdata uint8_t *ptr = (ADDR) + ((INDEX)*3);                               \
    ptr[0] = (B);                                                              \
    ptr[1] = (R);                                                              \
    ptr[2] = (G);                                                              \
  };
#define set_pixel_for_BGR_LED(ADDR, INDEX, R, G, B)                            \
  {                                                                            \
    __xdata uint8_t *ptr = (ADDR) + ((INDEX)*3);                               \
    ptr[0] = (B);                                                              \
    ptr[1] = (G);                                                              \
    ptr[2] = (R);                                                              \
  };

#endif


WS2812_pins_header.h的程式碼:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
// This file is generated by a script.

#ifndef _WS2812_PIND_HEADER_H_INCLUDED

#define _WS2812_PIND_HEADER_H_INCLUDED

void neopixel_show_long_P1_0(uint32_t dataAndLen);

#define neopixel_show_P1_0(ADDR, LEN)                                          \
  neopixel_show_long_P1_0((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_1(uint32_t dataAndLen);

#define neopixel_show_P1_1(ADDR, LEN)                                          \
  neopixel_show_long_P1_1((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_2(uint32_t dataAndLen);

#define neopixel_show_P1_2(ADDR, LEN)                                          \
  neopixel_show_long_P1_2((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_3(uint32_t dataAndLen);

#define neopixel_show_P1_3(ADDR, LEN)                                          \
  neopixel_show_long_P1_3((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_4(uint32_t dataAndLen);

#define neopixel_show_P1_4(ADDR, LEN)                                          \
  neopixel_show_long_P1_4((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_5(uint32_t dataAndLen);

#define neopixel_show_P1_5(ADDR, LEN)                                          \
  neopixel_show_long_P1_5((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_6(uint32_t dataAndLen);

#define neopixel_show_P1_6(ADDR, LEN)                                          \
  neopixel_show_long_P1_6((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P1_7(uint32_t dataAndLen);

#define neopixel_show_P1_7(ADDR, LEN)                                          \
  neopixel_show_long_P1_7((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_0(uint32_t dataAndLen);

#define neopixel_show_P3_0(ADDR, LEN)                                          \
  neopixel_show_long_P3_0((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_1(uint32_t dataAndLen);

#define neopixel_show_P3_1(ADDR, LEN)                                          \
  neopixel_show_long_P3_1((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_2(uint32_t dataAndLen);

#define neopixel_show_P3_2(ADDR, LEN)                                          \
  neopixel_show_long_P3_2((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_3(uint32_t dataAndLen);

#define neopixel_show_P3_3(ADDR, LEN)                                          \
  neopixel_show_long_P3_3((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_4(uint32_t dataAndLen);

#define neopixel_show_P3_4(ADDR, LEN)                                          \
  neopixel_show_long_P3_4((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_5(uint32_t dataAndLen);

#define neopixel_show_P3_5(ADDR, LEN)                                          \
  neopixel_show_long_P3_5((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_6(uint32_t dataAndLen);

#define neopixel_show_P3_6(ADDR, LEN)                                          \
  neopixel_show_long_P3_6((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

void neopixel_show_long_P3_7(uint32_t dataAndLen);

#define neopixel_show_P3_7(ADDR, LEN)                                          \
  neopixel_show_long_P3_7((((uint16_t)(ADDR)) & 0xFFFF) |                      \
                          (((uint32_t)(LEN)&0xFF) << 16));

#endif

2024年12月8日 星期日

[8051] 用CH552讀取語音IC的狀態

參考資訊:PXT-ASRPlanetX_MicroPython

電路圖:


程式碼:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <Arduino.h>

#define SDA_PIN 31 // 定義 SDA 為 P2
#define SCL_PIN 30  // 定義 SCL 為 P3

#define I2C_DELAY_US 5  // I²C 時鐘延遲 (調整延遲來控制速率)

// 語音設備 I²C 位址
#define VOICE_I2C_ADDR 0x0B

// 初始化 I²C 線路
void i2c_init() {
  pinMode(SDA_PIN, OUTPUT);
  pinMode(SCL_PIN, OUTPUT);
  digitalWrite(SDA_PIN, HIGH);
  digitalWrite(SCL_PIN, HIGH);
}

// 產生 I²C 起始信號
void i2c_start() {
  digitalWrite(SDA_PIN, HIGH);
  digitalWrite(SCL_PIN, HIGH);
  delayMicroseconds(I2C_DELAY_US);
  digitalWrite(SDA_PIN, LOW);
  delayMicroseconds(I2C_DELAY_US);
  digitalWrite(SCL_PIN, LOW);
}

// 產生 I²C 停止信號
void i2c_stop() {
  digitalWrite(SDA_PIN, LOW);
  digitalWrite(SCL_PIN, HIGH);
  delayMicroseconds(I2C_DELAY_US);
  digitalWrite(SDA_PIN, HIGH);
  delayMicroseconds(I2C_DELAY_US);
}

// 傳送 1 個位元
void i2c_send_bit(bool bit) {
  digitalWrite(SDA_PIN, bit);
  delayMicroseconds(I2C_DELAY_US);
  digitalWrite(SCL_PIN, HIGH);
  delayMicroseconds(I2C_DELAY_US);
  digitalWrite(SCL_PIN, LOW);
}

// 接收 1 個位元
bool i2c_read_bit() {
  pinMode(SDA_PIN, INPUT);
  delayMicroseconds(I2C_DELAY_US);
  digitalWrite(SCL_PIN, HIGH);
  delayMicroseconds(I2C_DELAY_US);
  bool bit = digitalRead(SDA_PIN);
  digitalWrite(SCL_PIN, LOW);
  pinMode(SDA_PIN, OUTPUT);
  return bit;
}

// 傳送 1 個位元組 (8 位元) 並讀取 ACK/NACK
bool i2c_write_byte(uint8_t data) {
  for (uint8_t i = 0; i < 8; i++) {
    i2c_send_bit(data & 0x80);
    data <<= 1;
  }
  // 接收 ACK/NACK
  return !i2c_read_bit();  // 0: ACK, 1: NACK
}

// 讀取 1 個位元組 (8 位元)
uint8_t i2c_read_byte(bool ack) {
  uint8_t data = 0;
  for (uint8_t i = 0; i < 8; i++) {
    data <<= 1;
    if (i2c_read_bit()) {
      data |= 0x01;
    }
  }
  i2c_send_bit(!ack);  // 傳送 ACK (0) 或 NACK (1)
  return data;
}

// 寫入資料到 I²C 裝置
bool i2c_write(uint8_t addr, uint8_t *data, uint8_t len) {
  i2c_start();
  if (!i2c_write_byte(addr << 1)) {  // 傳送寫入位址
    i2c_stop();
    return false;
  }
  for (uint8_t i = 0; i < len; i++) {
    if (!i2c_write_byte(data[i])) {  // 傳送資料
      i2c_stop();
      return false;
    }
  }
  i2c_stop();
  return true;
}

// 從 I²C 裝置讀取資料
bool i2c_read(uint8_t addr, uint8_t *buffer, uint8_t len) {
  i2c_start();
  if (!i2c_write_byte((addr << 1) | 1)) {  // 傳送讀取位址
    i2c_stop();
    return false;
  }
  for (uint8_t i = 0; i < len; i++) {
    buffer[i] = i2c_read_byte(i < (len - 1));  // 除了最後一個位元組外,都傳送 ACK
  }
  i2c_stop();
  return true;
}

// 讀取語音 I²C 設備的資料
bool read_voice_data(uint8_t *buffer, uint8_t len) {
  return i2c_read(VOICE_I2C_ADDR, buffer, len);  // 從語音設備讀取資料
}

void setup() {

  i2c_init();
}

void loop() {
  uint8_t voice_data[2];  // 用來接收語音設備的資料

  // 從語音設備讀取資料
  if (read_voice_data(voice_data, 1)) {
    USBSerial_print("Voice Data: ");
    USBSerial_println(voice_data[0], HEX);  // 顯示語音設備的第1個位元組
  } else {
    USBSerial_print("Failed to read voice data\n");
  }

  delay(100);  // 等待 100 msec
}

執行結果:
Voice Data: 0
Voice Data: 1
Voice Data: 0
Voice Data: 0
Voice Data: 0
Voice Data: 0
Voice Data: 0
Voice Data: 0
Voice Data: 11

2024年12月7日 星期六

[8051] CH552初接觸-拍手聲控馬達

電路圖:




零件:CH552、EF92-A  micro:servo 180、KS0035 Microphone Sound Sensor with Potentiometer

程式碼:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <Servo.h>
const int analogInPin = 11;  
const int servoPin = 15; 
int threshold = 60;

int sensorValue = 0;        // value read from the pot

void setup() {
  pinMode(analogInPin,INPUT);
  Servo_init();
  pinMode(servoPin, OUTPUT);
  Servo_attach(servoPin);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);
  
  USBSerial_print("sensor = ");
  USBSerial_print(sensorValue);
    USBSerial_print("\n");
 
  if (sensorValue>=threshold){
    Servo_write(servoPin,90);
    delay(1000);
    Servo_write(servoPin,0);
    delay(1000);
    Servo_write(servoPin,180);
    delay(1000);
    Servo_write(servoPin,0);
    delay(1000);
    Servo_write(servoPin,90);

  }
  delay(2);
}