sudo apt-get install openssh-server
2024년 12월 27일 금요일
2024년 12월 23일 월요일
2024년 11월 27일 수요일
arduino mega 2560, ramps 1.4, lcd2004 temperature control
arduino Mega 2560
ramps 1.4 board
lcd 2004 board
참조링크 Hacking Arduino Mega/RAMPS 3D Printer Shield to Control Any Project : 4 Steps - Instructables
#include <math.h>
#include <SPI.h>
#include <LiquidCrystal.h> // LCD 라이브러리
#include "ClickEncoder.h"
#include "Thermistor.h"
#include "pin_map.h"
// LCD 핀 연결
const int rs = 16, en = 17, d4 = 23, d5 = 25, d6 = 27, d7 = 29;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // LiquidCrystal 객체 초기화
// 히터 핀 설정 (Ramps 1.4 보드)
const int heater1Pin = 10; // HEATER 1 핀
const int heater2Pin = 9; // HEATER 2 핀
// 부저 핀 설정
const int buzzerPin = 37; // 부저 핀 (37번 핀으로 설정)
bool Running = true;
int units = 0; // Celcius
int16_t last, value; // store position of encoder
float Temp_C = 0;
float setpoint = 0.0; // 초기 설정 온도 (0.0도)
unsigned int sensorReadFreq = 1; // Hz
Thermistor Thermistor1(TEMP_0_PIN); //Create instance of Thermistor class
ClickEncoder *encoder; //Create instance of ClickEncoder class
// 상태 변수
bool settingMode = false; // 설정 모드인지 확인하는 변수
// Time variables
unsigned long lastUpdateTime = 0; // To track the last time the display was updated
const unsigned long updateInterval = 200; // 200 ms update interval for loop
// 부저 제어를 위한 변수
unsigned long buzzerStartTime = 0;
bool buzzerState = false;
bool buzzerActivated = false; // 부저가 울렸는지 확인하는 변수
bool initialRun = true; // 처음 실행 여부를 확인하는 변수
void setup() {
Serial.begin(115200);
Serial.println("RAMPS TEST");
// LCD 초기화
lcd.begin(16, 2); // 16x2 LCD 사용
lcd.setCursor(0, 0);
lcd.print("Starting...");
// Set up click encoder
encoder = new ClickEncoder(D33, D31, D35);
last = -1;
// Initialize heaters
pinMode(heater1Pin, OUTPUT);
pinMode(heater2Pin, OUTPUT);
// Initialize buzzer pin
pinMode(buzzerPin, OUTPUT); // 부저 핀 초기화
digitalWrite(buzzerPin, LOW); // 부저 끄기
// 초기 히터 끄기
digitalWrite(heater1Pin, LOW);
digitalWrite(heater2Pin, LOW);
// Initialize timers
noInterrupts(); // disable all interrupts
// Sensor read timer
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = round(16000000 / 256 / sensorReadFreq); // compare match register 16MHz/256/1Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
// Encoder read timer
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
OCR2A = round(16000000 / 1024 / 1000); // compare match register e.g. 16MHz/1024/100Hz
TCCR2B |= (1 << WGM12); // CTC mode
TCCR2B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt
interrupts(); // enable all interrupts
lastUpdateTime = millis(); // Record the time at the end of setup
}
// ----------------------------------------------------------------------------
// TIMER ISRs
// ----------------------------------------------------------------------------
ISR(TIMER1_COMPA_vect) {
Temp_C = Thermistor1.getValue(); // read temperature from thermistor
Serial.println(Temp_C);
}
ISR(TIMER2_COMPA_vect) {
encoder->service();
}
// ----------------------------------------------------------------------------
void loop() {
unsigned long currentMillis = millis(); // Get current time
// Update temperature and display every 200ms
if (currentMillis - lastUpdateTime >= updateInterval) {
lastUpdateTime = currentMillis;
lcd.clear(); // 화면 초기화
lcd.setCursor(0, 0); // 첫 번째 줄에 온도 표시
lcd.print("Temp: ");
lcd.print(Temp_C, 1); // 온도값을 소수점 첫째자리까지 출력
lcd.print(" C");
// 설정 온도를 LCD에 표시
lcd.setCursor(0, 1); // 두 번째 줄에 설정 온도 표시
if (settingMode) {
lcd.print("Setting: "); // 설정 모드일 때 "Setting" 표시
lcd.print(setpoint, 1); // 설정 온도 소수점 첫째자리까지 출력
lcd.print(" C");
} else {
lcd.print("Set: "); // 설정 모드가 아닐 때 "Set" 표시
lcd.print(setpoint, 1); // 설정 온도 소수점 첫째자리까지 출력
lcd.print(" C");
}
}
// ClickEncoder processing, runs independently of the temperature update cycle
value += encoder->getValue();
// 엔코더 값이 변경되면, 설정 모드일 때만 온도 변경이 반영되도록 설정
if (value != last) {
if (settingMode) {
setpoint = -value / 5.0; // value를 -5로 나누어 온도 변화 속도를 반대로 설정
if (setpoint > 100.0) setpoint = 100.0; // 100도 이상으로 설정할 수 없게 제한
if (setpoint < 0.0) setpoint = 0.0; // 0도 이하로 설정할 수 없게 제한
Serial.print("Setpoint: ");
Serial.println(setpoint);
buzzerActivated = false; // 설정 온도 변경 시 부저 상태 초기화
initialRun = false; // 처음 실행 여부를 초기화
}
last = value;
}
// 엔코더 버튼 처리 (설정 모드 변경 및 저장)
ClickEncoder::Button b = encoder->getButton();
if (b != ClickEncoder::Open) {
switch (b) {
case ClickEncoder::Clicked:
if (settingMode) {
settingMode = false; // 설정 모드 종료
Serial.println("Settings saved!");
} else {
settingMode = true; // 설정 모드로 진입
Serial.println("Entering setting mode...");
}
break;
case ClickEncoder::Pressed:
break;
case ClickEncoder::DoubleClicked:
break;
}
}
// 온도에 따른 히터 제어 (설정 모드가 아닐 때만)
if (!settingMode) {
if (Temp_C < setpoint) {
digitalWrite(heater1Pin, HIGH); // 히터1 켜기
digitalWrite(heater2Pin, HIGH); // 히터2 켜기
} else {
digitalWrite(heater1Pin, LOW); // 히터1 끄기
digitalWrite(heater2Pin, LOW); // 히터2 끄기
// 설정 온도에 도달하면 부저를 2초동안 울리기 (한 번만)
if (Temp_C >= setpoint && !buzzerActivated && !initialRun) {
buzzerState = true; // 부저 상태 변경
buzzerStartTime = millis(); // 부저 시작 시간 기록
buzzerActivated = true; // 부저가 울렸음을 표시
}
}
}
// 부저 제어 (부저 상태에 따라 타이머로 제어)
if (buzzerState) {
if (millis() - buzzerStartTime < 1000) {
digitalWrite(buzzerPin, HIGH); // 부저 켜기
} else {
digitalWrite(buzzerPin, LOW); // 부저 끄기
buzzerState = false; // 부저 상태 리셋
}
}
}
2024년 7월 8일 월요일
modbus RTU / TCP-IP
전주 modbus 개발 ittang@naver.com
modbus RTU
Id / function code / data / crc
modbus over TCP (KG30X)
Id / function code / data / crc
modbus TCP/IP
transaction id (2byte) / protocol id (0x00 고정) / langth (2byte) / slave id (1byte)
----------------------------------------------------------------------------------MBAP Header
MBAP Header + function code (1byte) + nData (nByte)
2024년 6월 30일 일요일
GrblGru GRBL CNC
inkscape make file text >> PATH manu >> object to path
save file to svg
grblgru import svg
2D job make >> process
Depth increment setting
sum of increment setting
save g-code >> edit to spindle code insert >> M3 S2000
grblgru >> file >> load g-code >> start to endmill