728x90
반응형
오늘은 기기를 만들었습니다.
사용한 부품 및 장치
진동자: Hapcoil-one
가속도계: ADXL354
https://sillon-coding.tistory.com/632
[Haptics - Haptuator Single Frequency] Calibration Using NI DAQ and Python
1. 실험 개요진동자를 활용한 가속도 측정에서는 신호의 정확한 보정이 필수적입니다. 본 실험에서는 Single Frequency Calibration을 수행하여, 특정 주파수에서 입력 전압과 출력 가속도 값의 관계를
sillon-coding.tistory.com
펠티어모듈 : thermoREAL
서미스터(온도 측정)
아두이노 모터 드라이버 2A L298N / Arduino Motor driver
아두이노 우노
근데 뭔지는 안알려줄거임 ㅋ
개멋있어 강수연
회로는 아래와 같습니다
#include <PID_v1.h>
#define PWM 10
#define PHASE1 2
#define PHASE2 3
#define PWM2 11
#define PHASE3 4
#define PHASE4 5
int Vi = 1023;
float R1 = 22000;
float c1 = -1.185559046e-03;
float c2 = 5.505203063e-04;
float c3 = -9.653138374e-07;
// Sensor 1 (A0)
double input = 0, output = 0, prevInput = 0;
double init_setpoint = 32.5;
double setpoint = init_setpoint;
// Sensor 2 (A1)
double input2 = 0, output2 = 0, prevInput2 = 0;
double init_setpoint2 = 32.5;
double setpoint2 = init_setpoint2;
// PID Parameters
double Kp = 60, Ki = 0.6, Kd = 0.5;
PID myPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
PID myPID2(&input2, &output2, &setpoint2, Kp, Ki, Kd, DIRECT);
String serialBuffer = "";
void setup() {
Serial.begin(115200);
pinMode(PWM, OUTPUT); pinMode(PHASE1, OUTPUT); pinMode(PHASE2, OUTPUT);
pinMode(PWM2, OUTPUT); pinMode(PHASE3, OUTPUT); pinMode(PHASE4, OUTPUT);
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(-255, 255);
myPID2.SetMode(AUTOMATIC);
myPID2.SetOutputLimits(-255, 255);
Serial.println("READY");
}
void loop() {
if (Serial.available()) {
String inputLine = Serial.readStringUntil('\n');
inputLine.trim(); // 앞뒤 공백 제거
int spaceIndex = inputLine.indexOf(' '); // 공백 위치 찾기
if (spaceIndex > 0) {
String part1 = inputLine.substring(0, spaceIndex);
String part2 = inputLine.substring(spaceIndex + 1);
float delta1 = part1.toFloat();
float delta2 = part2.toFloat();
setpoint = init_setpoint + delta1;
setpoint2 = init_setpoint2 + delta2;
// 디버그 출력
Serial.print("[INPUT OK] delta1: ");
Serial.print(delta1);
Serial.print(" → setpoint1: ");
Serial.println(setpoint);
Serial.print("[INPUT OK] delta2: ");
Serial.print(delta2);
Serial.print(" → setpoint2: ");
Serial.println(setpoint2);
} else {
Serial.println("[ERROR] Input must be two space-separated numbers, like: 5 -3");
}
}
// Sensor 1
double rawInput = ReadTemperature(A0);
input = 0.4 * prevInput + 0.6 * rawInput;
prevInput = input;
// Sensor 2
double rawInput2 = ReadTemperature(A1);
input2 = 0.4 * prevInput2 + 0.6 * rawInput2;
prevInput2 = input2;
myPID.Compute();
myPID2.Compute();
SetOutputDirection(output, input, setpoint, PWM, PHASE1, PHASE2);
SetOutputDirection(output2, input2, setpoint2, PWM2, PHASE3, PHASE4);
// Pretty one-line status output
Serial.print("CH1: ");
Serial.print(input, 2);
Serial.print("°C → ");
Serial.print(setpoint, 2);
Serial.print("°C | PWM: ");
Serial.print(abs(output), 0);
Serial.print(" || CH2: ");
Serial.print(input2, 2);
Serial.print("°C → ");
Serial.print(setpoint2, 2);
Serial.print("°C | PWM: ");
Serial.println(abs(output2), 0);
delay(100); // 10Hz
}
double ReadTemperature(int pin) {
int Vo = analogRead(pin);
if (Vo <= 0) return -999.0;
float R2 = R1 * (Vi / (float)Vo - 1.0);
float logR2 = log(R2);
return (1.0 / (c1 + c2 * logR2 + c3 * pow(logR2, 3))) - 273.15;
}
void SetOutputDirection(double out, double inTemp, double targetTemp,
int pwmPin, int ph1, int ph2) {
double pwmVal = abs(out);
digitalWrite(ph1, inTemp < targetTemp ? LOW : HIGH);
digitalWrite(ph2, inTemp < targetTemp ? HIGH : LOW);
analogWrite(pwmPin, pwmVal);
}
입력예시
3 -6
32.5 도가 기본 온도임
저렇게 입력하면 한쪽 펠티어에 32.5 + 3 = 35.5 도로 제어되고,
다른 한쪽에선 32.5 - 6 = 26.5도로 제어됨
728x90
반응형