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