라즈베리파이_리눅스(I2C, PWM)

공이지·2024년 7월 3일

I2C ?

  • 2개의 선을 이용한 통신방식입니다.
  • 하나의 Master와 여러개의 Slave 기기가 물려 통신이 가능합니다.(Master Slave F/F)
  • clock신호를 사용하는 동기식 통신방식이라 시간에 자유롭다.
  • Slave선택을 위해 항상 주소 데이터가 붙기때문에 긴 데이터를 전송하기에는 부적합한 통신 방식.

  • I2C는 clock으로 싱크를 맞추기 위한 SCL, 실제 데이터를 주고 받는 SDA선이 존재한다.
  • 이 둘은 풀업저항으로 HIGH값이 Default이다.
    _ SCL이 High일때 SDA가 LOW로 변하는 순간 통신의 시작을 알리는 신호입니다. 이후 SCL은 HIGH,LOW를 반복하는 주기를 가져 통신에 싱크를 맞춥니다.
  • 위의 타이밍도에서 파란색 부분이 SCL = LOW 일때 SDA에서 HIGH or LOW를 결정하여 통신을 준비하고, 실제로 통신을 하는 부분은 초록색 부분입니다. SDA가 HIGH냐 LOW냐를 통해 데이터를 쓰거나 읽습니다. 데이터 통신이 끝낫다면 SCL이 HIGH신호를 주고, SDA도 HIGH신호를 주면서 통신을 중지합니다.

ADC 컨버터(YL-40)

  • 아날로그 디지털 변환(ADC: Analog to Digital Converter) : 아날로그 전기 신호를 디지털 신호로 변환하는 회로.

    기본적으로 아날로그 신호를 디지털 신호로 변환하는 회로인것은 알겠는데 어떤 과정을 거쳐서 디지털 신호로 전환하느냐?
    1. Sampling(표본화) : 아날로그 신호를 일정한 시간 간격을 가지고 해당 시간 간격마다 아날로그 신호를 채취하는 것을 말합니다. 이는 시간에 따라 연속적으로 변화하는 아날로그 신호들 중에서 특정한 매 시간 간격마다 그 아날로그 신호만을 취득하는 의미입니다. 아래 그림처럼 회색으로 나타낸 아날로그 신호를 일정한 시간 간격으로 나눈 후 그 시간 간격에 해당하는 아날로그 신호값을 채취하는 표본화의 모습을 나타낸 그래프입니다.

    2. Quantization(양자화) : 이는 표본화 과정으로 아날로그 신호를 일정한 전압 레벨의 구간을 나눈 영역에 강제적으로 대응 시키는 과정입니다. 양자화를 할 때 해상도(Resolution)이 중요합니다. 전압 레벨 구간을 촘촘하게 나누면 나눌수록 처리할 데이터 양은 많겠지만 원래 아날로그 신호에 매우 근사하게 접근할 수 있습니다. 이렇게 아날로그 신호를 전압 레벨에 따라서 구간을 나눠 이를 강제적으로 대응하게 하는것이 양자화 입니다.

    3. 부호화(Encoding) : 표본화와 양자화가 상호적으로 이뤄진 후에 얻어진 데이터를 가지고 2진수의 코드를 부여하는 과정입니다. 이는 해상도(Resolution)에 따라서 코드의 경우의 수가 결정되는 것이 일반적입니다. 만약 4bit이라면 0000~1111까지 16개의 코드를 부여할 수 있습니다.

I2C 실습

gpio readall : 라즈베리파이 핀을 확인하는 명령어.

  • wpi핀번호 8,9가 기본적으로 설정되어있는 i2c핀번호입니다. 채널 1(SCL1, SDA1)에 속합니다.
    i2cdetect -y 1 : 우리는 채널 1에 YL-40을 연결했으므로 다음 명령어를 통해 채널 1에 연결되어있는 주소를 확인해줍니다.

  • 스스로 작성한 코드입니다. 채널 1의 주소는 48이므로 처음에 디바이스를 초기화 하는 작업을 해줍니다. 이 후 우리가 사용할 입력 채널을 선택합니다. 0~3번까지 채널이 존재합니다(0 : 조도샌서, 1 : 온도센서, 2 : 비어있음, 3 : 가변저항) 우리가 초기화한 디바이스를 몇번 채널의 신호를 읽어올지 결정한 뒤 wiringPiI2CRead()를 통해 디지털 신호로 변환하여 변경된 신호를 읽어옵니다.

  • 수정코드와 실행결과입니다. 하지만 초기화하는 코드 부분을 저렇게 따로 할 필요가 없다고 하셨습니다.

  • 최종 코드와 실행결과입니다. 여기선는 조이스틱을 0,1번 입력채널에 연결하여 x,y좌표 값을 아날로그 신호 입력을 받아서 움직인 좌표에 명령어 창의 커서가 움직이면서 좌표값을 표시하도록 하였습니다.

  • 코드 설명 및 정리

    YL-40(ADC컨버터)는 I2C 인터페이스 제공하여 I2C통신으로 ADC컨버터의 기능을 수행합니다.

  • #include <wiringPiI2C.h> : I2C를 사용하기 위해서 코드의 선언부에 선언.

  • int dh1 = wiringPiI2CSetup(0x48); : i2cdetect -y 1 이라는 명령어를 cmd창을 활용해 연결된 디바이스 채널을 확인하여 초기화 시켜줍니다.

  • wiringPiI2CWrite(dh1,0); : 채널을 초기화한 함수는 int형 함수이므로 int 타입의 변수로 저장을하고 사용할 0번 채널을 준비시키라는 의미.

  • wiringPiI2CRead(dh1); : 중간에 int 타입의 변수로 값을 읽어오기전에 초기화하는 과정을 진행합니다. 이는 사용한 채널을 set해주거나 다음 채널을 사용하기위해 사용한 채널을 초기화 시켜주기 위해서 진행합니다.

  • int val1 = wiringPiI2CRead(dh1); : 0번채널로 받은 아날로그의 값을 변수에 저장하여 우리가 확인할 수 있는 디지털신호로 변환하는 과정(smapling?)

PWM ?

  • 디지털 신호 중 특정한 형태를 띈 신호를 일컷는 용어입니다. 이는 회로제어에 다양한 용도로 활용되며 가장 쉽게 PWM을 사용한 예시는 RGBLED의 색상변경이나 서브모터의 방향 전환에서 볼 수 있습니다. 이들은 모두 디지털신호일지라도 PWM을 사용하면 아날로그 신호와 유사한 효과를 낼 수 있습니다. 이는 일정한 주기의 디지털 신호의 출력이 HIGH인 시간과 LOW인 시간의 비율을 조정해서 아날로그 효과를 내는 방법이므로 디지털신호만을 사용하는 마이크로 컨트롤러에서 아날로그 신호를 만들 필요가 있을 때 유용하게 사용됩니다.

원리 및 실습

  • 실습 코드를 보면 dutyrate를 입력하여 Duty Cycle을 계산합니다 이 DutyCycle은 신호의 High와 Low의 비율을 의미합니다. 만약 50을 입력하면DutyCycle은 5:5가 되면서 LED가 일정하게 깜빡거릴것입니다. 하지만 위 코드는 밝기를 조절할 수 있도록 작성한 코드입니다. 입력한 DutyRate가 높으면 높을수록 더 밝은 빛을 발산합니다. 이유는 DutyCycle의 Low비율이 High의 비율보다 많기 때문에 더 어둡게 보이고 High의 비율이 더 많으면 밝게보이게됩니다.
  • 위처럼 반복문을 사용하여 PWM핀번호에 연결된 LED를 끄고 켜고 할 수있지만, 다음처럼 Thread를 사용하는 방식을 사용할 수 있습니다.
  • 이처럼 create를 통해 쓰레드를 생성해서 반복문 없이 LED가 pwm방식으로 동작한다. 이때 stop을 해주면 할당한 쓰레드를 해지시켜 동작이 멈추게됩니다.

DutyCycle

  • PWM은 DutyCycle로 디지털 신호를 아날로그신호를 만듭니다. 위와 같이 High신호와 Low 신호의 비율을 표시하기 위해 DutyCycle이라는 용어가 사용되고 이는 HIGH와 LOW 신호의 비율입니다.

PWM 주파수 = 19.2MHz
우리가 원하는 주파수를 만들기 위해서는 설정값을 바꿔줘야한다.
pwmSetRange(unsigned int range) : 우리가 사용하고자 하는 주파수 범위를 지정해준다,
pwmSetClock(int divisor) : 우리가 원하는 주파수를 갖기 위해서 pwm 주파수를 분주율과 계산해야합니다.
즉, 19.2MHz를 갖는 PWM 하드웨어에서 우리가 원하는 주파수를 설정하기위해서
preScaler를 사용하여 분주율을 설정하여 원하는 PWM주파수와 계산하여 원하는 주파수를 얻을 수 있다.

profile
화이팅..!

0개의 댓글