좀더 hal 코드를 써서 고생을 해봐야하나..

아무튼, 간단하게  float input 으로 바꾸기 위해 input mode로 바꾸고

output mode로 바꾸고 나서는 출력을 써줘야 된다.

#define BUF_SIZE 50
uint8_t usb_buf[BUF_SIZE];
uint32_t count = 0;
#if 1
int prev_val = 0;

// STM32F1: 4 bits per pin (CNF[1:0] MODE[1:0]) in CRL (pins 0-7) / CRH (pins 8-15)
static inline void pin_set_cfg(GPIO_TypeDef *port, uint16_t pin, uint32_t cfg)
{
    uint32_t num = __builtin_ctz(pin);
    uint32_t *reg = (num < 8U) ? &port->CRL : &port->CRH;
    uint32_t pos = (num % 8U) * 4U;
    *reg = (*reg & ~(0xFU << pos)) | (cfg << pos);
}

static inline void pin_hiz(GPIO_TypeDef *port, uint16_t pin)
{
    pin_set_cfg(port, pin, 0x4U);  // CNF=01 MODE=00: floating input (Hi-Z)
}

static inline void pin_output(GPIO_TypeDef *port, uint16_t pin)
{
    pin_set_cfg(port, pin, 0x2U);  // CNF=00 MODE=10: push-pull output, 2 MHz
}

void gpio_proc()
{
  int val = 0;
  // row
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) << 4);
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) << 5);
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) << 6);
  // val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) << 7);

  char *swname[4][4] = {
    {"S1", "S2", "S3", "S4"},
    {"S5", "S6", "S7", "S8"},
    {"S9", "S10", "S11", "S12"},
    {"S13", "S14", "S15", "S16"}
  };

  for(uint16_t row_idx = 0; row_idx < 4; row_idx ++)
  {
    uint16_t pin_arr[] = {GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7};
    pin_output(GPIOA, pin_arr[row_idx]);
    HAL_GPIO_WritePin(GPIOA, pin_arr[row_idx], GPIO_PIN_SET);
    
    HAL_Delay(1);

    // column
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) << 0);
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) << 1);
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) << 2);
    val |= (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) << 3);

    // HAL_GPIO_WritePin(GPIOA, pin_arr[row_idx], GPIO_PIN_RESET);
    pin_hiz(GPIOA, pin_arr[row_idx]);

    int col_idx = 0;
    for(int col_idx = 0; col_idx < 4; col_idx++)
    {
      if((val >> col_idx) & 0x01)
      {
        char *name = swname[row_idx][col_idx];
        sprintf((char*)usb_buf + strlen(usb_buf), "%s ", name);
      }
    }

    val = 0;
  }

  sprintf((char*)usb_buf + strlen(usb_buf), " --- %d %X\r\n", count, val);
  CDC_Transmit_FS(usb_buf, BUF_SIZE);
  memset(usb_buf,0,BUF_SIZE);
  count++;

}
#endif

 

전에는 이건 되었는데

 

요건 안되었었는데 input mode로 바꾸고 나서 잘 된다.

 

 

+

S1 / S4 / S16을 눌렀는데 S13 가 눌린걸로 인식되는건 다이오드 달아야지 머..

Posted by 구차니
모종의 음모/CAN2026. 9. 14. 17:41

SAE J1939는 대형차량, OBD-2 는 JAE J1979로 경량 차량용

완전히 연관이 있는것도 아니고 없는것도 아니고 애매한 느낌

[링크 : https://en.wikipedia.org/wiki/SAE_J1939] 차량 구성 요소 간 통신 및 진단 프로토콜

 

GPS는 NMEA 0183 로 시리얼 포트. 

[링크 : https://en.wikipedia.org/wiki/NMEA_2000] NMEA2K , 센서/디스플레이 등 해군용 프로토콜


[링크 : https://ko.wikipedia.org/wiki/CANopen] 자동화 임베디드 시스템에 사용하는 통신 프로토콜

[링크 : https://en.wikipedia.org/wiki/ISO_11783] isobus / 트랙터 농업용 기기를 위한 통신 프로토콜

'모종의 음모 > CAN' 카테고리의 다른 글

MCP2515와 CAN2.0B  (0) 2026.09.14
can.. 개조?  (0) 2026.08.31
can 트랜시버 - SN65HVD230  (0) 2026.08.20
MCP2515 on rpi .. 2번째  (0) 2026.07.24
obd can  (0) 2026.07.23
Posted by 구차니
모종의 음모/CAN2026. 9. 14. 17:19

CAN2.0B 라는게 보여서 그럼 CAN1.0 이나 CAN2.0A도 있나 하고 찾아보는 중

• Implements CAN V2.0B at 1 Mb/s:
- 0 to 8-byte length in the data field
Standard and extended data and remote frames 

standard - 11bit



extended - 29bit



[링크 : https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP2515-Family-Data-Sheet-DS20001801K.pdf]

 

스펙까지 볼 여유가 안되니(!) 일단 요약된걸 맞다는 가정하에

AMP가 can이 통신이 깨지지 않고 통신한다라는 핵심 기능이고

id에 대해서 0이 우성 1이 열성이라 자기가 쏜걸 읽어서 값이 바뀌었나 보고

낮은 번호가 우성 id를 가지기에 더 우선권을 가지고, 높은 번호가 통신을 id 만 보고 포기하게 만드는 구조.

11비트: 차량 내부 제어 네트워크(파워트레인, 섀시), CANopen, OBD-II 요청(0x7DF)
29비트: SAE J1939(상용차), NMEA 2000(선박), ISO 11783(농기계). ID 안에 PGN, 우선순위, 소스 주소를 필드로 나눠 넣는 구조라 29비트가 필요합니다

AMP가 하는 일

이더넷의 CSMA/CD는 충돌이 나면 양쪽 다 전송을 포기하고 랜덤한 시간만큼 기다렸다가 재시도합니다. 보내던 프레임은 버려지고, 언제 성공할지 예측할 수 없습니다.

AMP는 다릅니다. 충돌이 나도 우선순위가 높은 프레임 하나는 중단 없이 계속 전송됩니다. 진 쪽만 조용히 물러나므로 버스 시간이 전혀 낭비되지 않습니다. 이걸 비파괴적 비트 단위 중재(non-destructive bitwise arbitration)라고 부릅니다.

작동 원리는 두 가지 성질에 기대고 있습니다.

버스가 wired-AND로 동작한다. 우성(0)이 열성(1)을 항상 덮어씁니다. 한 노드라도 0을 내보내면 버스 전체가 0이 됩니다.
모든 노드가 자기가 쓴 비트를 되읽는다. 중재 필드(식별자 + RTR)를 MSB부터 한 비트씩 내보내면서 매 비트마다 비교합니다.


진 노드들은 프레임을 버리지 않고 송신 버퍼에 그대로 들고 있다가, 버스가 다시 유휴 상태가 되면 자동으로 재시도합니다.

AMP가 만들어내는 결과

결정론적 지연이 보장됩니다. 우선순위가 가장 높은 메시지는 최악의 경우에도 "현재 전송 중인 프레임이 끝날 때까지"만 기다리면 됩니다. 실시간 제어에서 CAN이 오래 살아남은 이유입니다.

비트레이트와 버스 길이가 묶입니다. 중재가 성립하려면 한 비트 시간 안에 신호가 버스 끝까지 갔다가 돌아와 모든 노드가 같은 값을 봐야 합니다. 그래서 1Mbps면 약 40m, 125kbps면 500m 식으로 속도를 낮춰야 거리가 늘어납니다. 비트 타이밍에서 샘플 포인트를 비트 후반(보통 75~87.5%)에 두는 것도 이 때문입니다.

같은 ID를 두 노드가 쓰면 안 됩니다. ID가 동일하면 중재가 승자를 가리지 못하고 둘 다 끝까지 송신하는데, 데이터 내용이 다르면 그 지점에서 비트 에러가 터집니다. ID는 시스템 전체에서 유일해야 합니다.

우선순위 기아(starvation)가 생길 수 있습니다. 버스 부하가 높으면 낮은 우선순위 메시지가 계속 밀립니다. 그래서 실제 설계에서는 ID를 아무렇게나 배정하지 않고, 주기와 마감시간을 고려한 응답시간 분석(worst-case response time analysis)을 거쳐 우선순위를 정합니다.

참고로 CAN FD도 중재 구간만큼은 AMP를 그대로 씁니다. 고속 전환은 중재가 끝난 뒤 데이터 필드에서만 일어나기 때문에, 이 원리는 최신 CAN에서도 유효합니다.

[링크 : https://claude.ai/share/c17e28ff-b3f8-4953-918e-407f2c6987f3]

'모종의 음모 > CAN' 카테고리의 다른 글

can / 상위 프로토콜(?)  (0) 2026.09.14
can.. 개조?  (0) 2026.08.31
can 트랜시버 - SN65HVD230  (0) 2026.08.20
MCP2515 on rpi .. 2번째  (0) 2026.07.24
obd can  (0) 2026.07.23
Posted by 구차니
프로그램 사용/Blender2026. 9. 14. 11:45

이전에 찾은대로 vrm 플러그인을 설치하고

 

import 에 vrm이 생겼나 보고

 

드래그 하면, 어? 창이 뜬다?

import anyway 를 체크하면

 

커서에 %가 뜨면서 올라간다.

제법 오래걸리네.. 15.4MB 인데

은근히 제어점이 많은데

 

치마랑, 상의도 흔들어 댈수 있게 되어있고

머리카락도 찰랑찰랑이 가능해서 그런듯.

 

눈은 제법 작게 되어있어서 은근 찾기가 힘들다.

 

그나저나 손에 비하면 발은 언제나 단순하구만.

 

 

miko.vrm 파일은

glTF 를 기반으로 한 json 파트와, 바이너리로 구성되는 듯?

'프로그램 사용 > Blender' 카테고리의 다른 글

버튜버 모델 miko vrm  (0) 2026.09.09
blender sculpting - trim  (0) 2026.09.04
blender 객체 중심에 오게 하기  (0) 2026.09.04
blender spot light  (0) 2026.09.04
blender eevee / cycle 렌더 헤드리스  (0) 2026.09.04
Posted by 구차니

edit - preferences

 

midi - midi port config 에 가보면

악기 번호 이런것도 없고 그냥 바로 보인다.

 

in / out 모두 체크해주고

 

신나게 막 눌러보면 아래처럼 레벨미터가 뜬다.

 

근데 어떻게 기록하지?

'모종의 음모 > midi 피아노' 카테고리의 다른 글

악보 - 보표와 옥타브  (0) 2026.09.09
lmms 악기 교체(프로그램)  (0) 2026.09.09
피아노 운지법  (0) 2026.09.08
피아노 55잭에 소리가 작아!  (0) 2026.09.08
피아노 강좌  (0) 2026.09.04
Posted by 구차니

openSCAD 와 다르게 python / javascript 로 작동되는 파라매트릭 설계 라이브러리

 

[링크 : https://github.com/gumyr/build123d] python  기반

[링크 : https://fluidcad.io/] javascript 기반

    [링크 : https://wikidocs.net/blog/@jaehong/11371/]

'프로그램 사용 > openSCAD' 카테고리의 다른 글

openSCAD + claude.ai = 파라메트릭 모델링  (0) 2026.07.13
openSCAD MCP  (0) 2026.06.20
pythonSCAD  (0) 2026.06.20
openSCAD cheatsheet  (0) 2026.06.20
openSCAD 설치  (0) 2026.06.20
Posted by 구차니
embeded/Cortex-M3 STM2026. 9. 10. 21:41

흐음...?

일단 gpio 읽을 row high + col read 조합으로 하는데 (풀때는 row low)

col 하나가 눌리면 다른 row에서 해당 col은 읽히지가 않아서 찾아보니

high-z로 가야지 읽을수 있다고 한다. 테스트는 필요함

 

by claude

STM32 HAL에는 "Hi-Z로 쓰기" 함수가 없어서, 핀 모드를 **입력(No Pull)**으로 바꿔야 Hi-Z가 됩니다. 행을 스캔할 때만 출력으로 바꾸고, 끝나면 다시 입력으로 돌리면 됩니다.


static void row_pin_mode(uint16_t pin, uint32_t mode)
{
    GPIO_InitTypeDef init = {0};
    init.Pin   = pin;
    init.Mode  = mode;
    init.Pull  = GPIO_NOPULL;
    init.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &init);
}



static inline void pin_hiz(GPIO_TypeDef *port, uint16_t pin)
{
    uint32_t pos = __builtin_ctz(pin) * 2U;
    port->MODER &= ~(0x3U << pos);                               // 00: Input (Hi-Z)
}

static inline void pin_output(GPIO_TypeDef *port, uint16_t pin)
{
    uint32_t pos = __builtin_ctz(pin) * 2U;
    port->MODER = (port->MODER & ~(0x3U << pos)) | (0x1U << pos); // 01: Output
}

 

 

by chatgpt

GPIOA->CRL &= ~(0xF << (1 * 4));
GPIOA->CRL |=  (0x4 << (1 * 4));

여기서 0x4는:

MODE = 00  → Input
CNF  = 01  → Floating input

여러 핀을 한꺼번에

예를 들어 PA1, PA2, PA3을 모두 Hi-Z로:

GPIOA->CRL &= ~(
    (0xF << (1 * 4)) |
    (0xF << (2 * 4)) |
    (0xF << (3 * 4))
);

GPIOA->CRL |= (
    (0x4 << (1 * 4)) |
    (0x4 << (2 * 4)) |
    (0x4 << (3 * 4))
);
Posted by 구차니
프로그램 사용/freecad2026. 9. 10. 17:06

freeCAD에서 openFOAM을 이용해서 cfd 할 수 있는 플러그인

솔리드웍스 처럼 통합은 못해도 쓰는게 편하기라도 하면 좋겠네

 

[링크 : https://blog.naver.com/heennavi1004/223829709527]

[링크 : https://yyman.tistory.com/1053]

[링크 : https://blog.naver.com/localid/222302561603]

'프로그램 사용 > freecad' 카테고리의 다른 글

gemini + freecad  (0) 2025.09.01
claude mcp + freecad  (0) 2025.08.31
freeCAD + openFOAM  (0) 2025.08.29
freecad + MCP  (0) 2025.08.29
freecad on ubuntu 24.04  (0) 2025.05.18
Posted by 구차니

nvidia dgx 의 v100, a100 이런 애들이 쓰는 소켓인데

[링크 : https://en.wikipedia.org/wiki/SXM_(socket)]

 

맨날 이런 은색 8개만 있는 것들만 사진으로 봐서 8핀짜리 초고속 인터페이스 인가 싶어 검색해보니

이런식으로 접점이 어마어마한 녀석이었나 보다.

 

먼가.. nvidia에서 한거라서 그런가. jetson tx 모듈 커넥터 비슷한 느낌이기도 하다

[링크 : https://l4rz.net/running-nvidia-sxm-gpus-in-consumer-pcs/]

 

[링크 : https://connecttech.com/product/nvidia-jetson-tx2-module-900-83310-0001-000/]

'하드웨어 > 커넥터 (Connector)' 카테고리의 다른 글

i-pex 커넥터 MHF1 / MHF4L  (0) 2026.03.19
press fit type 커넥터  (0) 2025.05.16
FAKRA  (0) 2022.08.17
USB3.0 커넥터  (1) 2022.03.24
m.2 와 mini PCI-e  (0) 2022.01.26
Posted by 구차니

먼가 이해가 안되서 끄적끄적

row 0(윗줄)에 high로 흘리고

col 0 / col 1 에서 읽으면 키를 눌러서 연결되어있으니 둘 다 읽히고

 

row 1(아랫줄) 을 읽기 위해서 row 0을 low로 하고 row 1을 high로 하면

row 0, col 1 과 row 1, col 1이 전기적으로 이어지면서 row 1의 전기가 row 0로 넘어가게 되고

row0 를 타고 col 0에 들어가서

눌리지 않은 row 1, col 0이 눌린것으로 오인식되게 된다.

 

신기하네..

그래서 다이오드 쓴다고.

 

얘는 누르지 않아는데 눌린걸로 착각하는 "고스팅"

얘는 스캔라인이 다른데 두개 누르면 안눌린걸로 착각하게 되는 현상인데.. 이건 딱히 용어가 없네

잘은 모르겠지만.. col 쪽 gpio의 threshold를 넘길수 없어서 안눌린걸로 인식되는걸까?

다른 row는 0으로 되어있으니 다른쪽으로 쭈르르르륵 다 빨려들어가서 0으로 되거나?

+

GPT 말로는 2 key roll over / masking 이라고 표현한다고 하는데.. 맞나?

그리고 gpio를 row에서 low/high 값 대신 high-Z(init) / high로 해보란다.

레지스터 직접 건드리면 init까진 아니어도 된다는데 CRL 레지스터에 쓰면 된다고 한다.

 

블로킹은

소스코드(그러니까 작동 알고리즘상)에서 고스팅을 방지하기 위해서 어떤 키가 잘못 눌리는지 판단해서 차단해버리는거

여긴 진짜로 눌렀는데 고스팅 처리에 의해서 막혀서 안눌리게 되는걸 의미하는 듯.

Posted by 구차니