
- 아두이노 이더넷 ENC28J60 SPI B90

- ENC28J60 이더넷 컨트롤러(10MB)와 -HR911105A 네트워크 인터페이스 포함
- LINK/STATUS 와 power LED 가 구성돼있어 직관적인 확인 가능
- AMS1117-3.3가 포함되어 있어, 3.3V 전압 입력과 외부 전압으로도 구동 가능
- 입력 전압 : 3.3V ~ 5V(최대 7V)
- 작동 전류 : 250mA
- 크리스탈 : 25Mhz





- Microchip사의 ENC28J60 이더넷 컨트롤러 기반 이더넷 통신 모듈
- SPI 인터페이스 방식으로 아두이노 및 다양한 MCU 보드와 연결 가능
- 10Base-T 이더넷(10Mbps) 지원
- RJ45 이더넷 포트 내장 (HanRun HR911105A)
- 25MHz 크리스탈 오실레이터 탑재로 안정적인 통신 클럭 제공
- TCP/IP 스택을 소프트웨어로 구현하여 유연한 네트워크 제어 가능
- 저전력 동작으로 임베디드 네트워크 프로젝트에 적합
- 아두이노 이더넷 통신, IoT 실습, 원격 제어·모니터링 프로젝트에 활용 가능

- PCB크기 : 50mm X 33mm X 18mm

- 아두이노 이더넷 ENC28J60 SPI B90 * 1pcs


#include#include #include #include uint8_t mac[6] = { 0x00,0x01,0x02,0x03,0x04,0x05 }; EthernetServer server(23); EthernetClient modemClient; EthernetClient telnetClient; #ifdef SoftwareSerial_h SoftwareSerial SWSerial(2, 3); // RX, TX #else #define SWSerial Serial #endif #define DCD_PIN 4 unsigned long lastConnectCheck = 0; unsigned long prevCharTime = 0; unsigned long prevRingTime = 0; uint8_t modemEscapeState = 0; bool modemCommandMode = true; const PROGMEM uint8_t regDefaults[] = {2, '+', 3, '\r', 4, '\n', 5, 8, 6, 2, 7, 50, 8, 2, 9, 6, 10, 14, 11, 95, 12, 50, 25, 5, 38, 20}; const PROGMEM int linespeeds[] = {0, 75, 110, 300, 600, 1200, 2400, 4800, 7200, 9600, 12000, 14400}; #define NSPEEDS (sizeof(linespeeds)/sizeof(int)) #define REG_ESC 2 #define REG_CR 3 #define REG_LF 4 #define REG_BSP 5 #define REG_GUARDTIME 12 #define REG_TELNET 15 #define REG_LINESPEED 37 #define REG_CURLINESPEED 43 #define REG_WIFI_CHANNEL 99 #define RING_MILLIS 4500 enum { E_OK = 0, E_CONNECT, E_RING, E_NOCARRIER, E_ERROR, E_CONNECT1200, E_NODIALTONE, E_BUSY, E_NOANSWER, E_CONNECT600, E_CONNECT2400, E_CONNECT4800, E_CONNECT9600, E_CONNECT14400, E_CONNECT19200 }; struct TelnetStateStruct { uint8_t cmdLen; uint8_t cmd[4]; bool sendBinary; bool receiveBinary; bool receivedCR; bool subnegotiation; } modemTelnetState, clientTelnetState; #define MAGICVAL 0xF0E1D2C3B4A59687 struct ModemDataStruct { uint64_t magic; uint32_t baud; byte bits; byte parity; byte stopbits; byte silent; byte unused; char telnetTerminalType[32]; uint8_t reg[32]; uint8_t extCodes; uint8_t echo; uint8_t quiet; uint8_t verbose; } ModemData; void applySWSerialSettings() { SWSerial.flush(); SWSerial.end(); delay(100); SWSerial.begin(ModemData.baud); } void clearSWSerialBuffer() { // empty the serial buffer delay(100); while( SWSerial.available()>0 ) { SWSerial.read(); delay(10); } } void setup() { pinMode(DCD_PIN, OUTPUT); digitalWrite(DCD_PIN, LOW); EEPROM.get(0, ModemData); if( ModemData.magic != MAGICVAL ) { // use default settings memset(&ModemData, 0, sizeof(ModemData)); ModemData.magic = MAGICVAL; ModemData.baud = 9600; ModemData.bits = 8; ModemData.parity = 0; ModemData.stopbits = 1; ModemData.silent = false; strcpy(ModemData.telnetTerminalType, PSTR("vt100")); for(int i=0; i 1 ) {SWSerial.print('<'); SWSerial.print(b, HEX);} if( state.cmdLen==0 && b == T_IAC ) state.cmdLen = 1; else if( state.cmdLen==1 && b == T_SE ) { state.subnegotiation = false; state.cmdLen = 0; } else state.cmdLen = 0; return true; } // ---- handle CR-NUL sequences if( state.receivedCR ) { state.receivedCR = false; if( b==0 ) { // CR->NUL => CR (i.e. ignore the NUL) if( ModemData.reg[REG_TELNET]>1 ) SWSerial.print(F("<0d<00")); return true; } } else if( b == 0x0d && state.cmdLen==0 && !state.receiveBinary ) { // received CR while not in binary mode => remember but pass through state.receivedCR = true; return false; } // ---- handle IAC sequences if( state.cmdLen==0 ) { // waiting for IAC byte if( b == T_IAC ) { state.cmdLen = 1; state.cmd[0] = T_IAC; if( ModemData.reg[REG_TELNET]>1 ) {SWSerial.print('<'); SWSerial.print(b, HEX);} return true; } } else if( state.cmdLen==1 ) { if( ModemData.reg[REG_TELNET]>1 ) {SWSerial.print('<'); SWSerial.print(b, HEX);} // received second byte of IAC sequence if( b == T_IAC ) { // IAC->IAC sequence means regular 0xff data value state.cmdLen = 0; // we already skipped the first IAC (0xff), so just return 'false' to pass this one through return false; } else if( b == T_NOP || b == T_BREAK || b == T_GOAHEAD ) { // NOP, BREAK, GOAHEAD => do nothing and skip state.cmdLen = 0; return true; } else if( b == T_SB ) { // start of sub-negotiation state.subnegotiation = true; state.cmdLen = 0; return true; } else { // record second byte of sequence state.cmdLen = 2; state.cmd[1] = b; return true; } } else if( state.cmdLen==2 ) { // received third (i.e. last) byte of IAC sequence if( ModemData.reg[REG_TELNET]>1 ) {SWSerial.print('<'); SWSerial.print(b, HEX);} state.cmd[2] = b; bool reply = true; if( state.cmd[1] == T_WILL ) { switch( state.cmd[2] ) { case TO_SEND_BINARY: state.cmd[1] = T_DO; state.receiveBinary = true; break; case TO_ECHO: state.cmd[1] = T_DO; break; case TO_SUPPRESS_GO_AHEAD: state.cmd[1] = T_DO; break; default: state.cmd[1] = T_DONT; break; } } else if( state.cmd[1] == T_WONT ) { switch( state.cmd[2] ) { case TO_SEND_BINARY: state.cmd[1] = T_DO; state.receiveBinary = false; break; } state.cmd[1] = T_DONT; } else if( state.cmd[1] == T_DO ) { switch( state.cmd[2] ) { case TO_SEND_BINARY: state.cmd[1] = T_WILL; state.sendBinary = true; break; case TO_SUPPRESS_GO_AHEAD: state.cmd[1] = T_WILL; break; case TO_TERMINAL_TYPE: state.cmd[1] = ModemData.telnetTerminalType[0]==0 ? T_WONT : T_WILL; break; default: state.cmd[1] = T_WONT; break; } } else if( state.cmd[1] == T_DONT ) { switch( state.cmd[2] ) { case TO_SEND_BINARY: state.cmd[1] = T_WILL; state.sendBinary = false; break; } state.cmd[1] = T_WONT; } else reply = false; // send reply if necessary if( reply ) { if( ModemData.reg[REG_TELNET]>1 ) for(int k=0; k<3; k++) {SWSerial.print('>'); SWSerial.print(state.cmd[k], HEX);} client.write(state.cmd, 3); if( state.cmd[1] == T_WILL && state.cmd[2] == TO_TERMINAL_TYPE ) { // send terminal-type subnegoatiation sequence uint8_t buf[110], i, n=0; buf[n++] = T_IAC; buf[n++] = T_SB; buf[n++] = TO_TERMINAL_TYPE; buf[n++] = 0; // IS for(i=0; i<100 && ModemData.telnetTerminalType[i]>=32 && ModemData.telnetTerminalType[i]<127; i++) buf[n++] = ModemData.telnetTerminalType[i]; buf[n++] = T_IAC; buf[n++] = T_SE; client.write(buf, n); if( ModemData.reg[REG_TELNET]>1 ) for(int k=0; k '); SWSerial.print(buf[k], HEX);} } } // start over state.cmdLen = 0; return true; } else { // invalid state (should never happen) => just reset state.cmdLen = 0; } return false; } int strncmpi(const char *s1, const char *s2, size_t cchars) { char c1, c2; if ( s1==s2 ) return 0; if ( s1==0 ) return -1; if ( s2==0 ) return 1; if ( cchars==0 ) return 0; do { c1 = toupper(*s1); c2 = toupper(*s2); s1++; s2++; cchars--; } while ( (c1 != 0) && (c1 == c2) && (cchars>0) ); return (int)(c1 - c2); } int getConnectStatus() { int res; if( ModemData.reg[REG_LINESPEED]==0 ) { int i = 0; while( i 32 ) cmd[cmdLen++] = c; else if( cmdLen>0 && c == ModemData.reg[REG_BSP] ) cmdLen--; if( ModemData.echo ) { if( c == ModemData.reg[REG_BSP] ) { SWSerial.print(char(8)); SWSerial.print(' '); SWSerial.print(char(8)); } else SWSerial.print(c); } prevCharTime = millis(); } if( cmdLen==2 && toupper(cmd[0])=='A' && cmd[1]=='/' ) { c = ModemData.reg[REG_CR]; cmd[1] = 'T'; cmdLen = prevCmdLen; } if( c == ModemData.reg[REG_CR] ) { while( (millis()-prevCharTime)<100 ) { if( SWSerial.available() ) { SWSerial.read(); break; } } prevCmdLen = cmdLen; if( cmdLen>=2 && toupper(cmd[0])=='A' && toupper(cmd[1])=='T' ) { cmd[cmdLen]=0; int ptr = 2; bool connecting = false; int status = E_OK; while( status!=E_ERROR && ptr =0 ) printModemResult(status); // delay 1 second after a "CONNECT" message if( connecting ) delay(1000); } else if( cmdLen>0 ) printModemResult(E_ERROR); cmdLen = 0; } } void relayModemData() { if( modemClient && modemClient.connected() && modemClient.available() ) { int baud = ModemData.reg[REG_CURLINESPEED]==255 ? ModemData.baud : linespeeds[ModemData.reg[REG_CURLINESPEED]]; if( baud == ModemData.baud ) { // use full modem<->computer data rate unsigned long t = millis(); while( modemClient.available() && millis()-t < 100 ) { uint8_t b = modemClient.read(); if( !handleTelnetProtocol(b, modemClient, modemTelnetState) ) SWSerial.write(b); } } else if( modemClient.available() ) { // limit data rate static unsigned long nextChar = 0; if( millis()>=nextChar ) { uint8_t b = modemClient.read(); if( !handleTelnetProtocol(b, modemClient, modemTelnetState) ) { SWSerial.write(b); nextChar = millis() + 10000/baud; } } } } if( millis() > prevCharTime + 20*ModemData.reg[REG_GUARDTIME] ) { if( modemEscapeState==0 ) modemEscapeState = 1; else if( modemEscapeState==4 ) { // received [1 second pause] +++ [1 second pause] // => switch to command mode modemCommandMode = true; printModemResult(E_OK); } } if( SWSerial.available() ) { uint8_t buf[128]; int n = 0, millisPerChar = 1000 / (ModemData.baud / (1+ModemData.bits+ModemData.stopbits)) + 1; unsigned long startTime = millis(); if( millisPerChar<5 ) millisPerChar = 5; while( SWSerial.available() && n 0 && buf[n-1] == 0x0d && b != 0x0a ) buf[n++] = 0; } buf[n++] = b; prevCharTime = millis(); if( modemEscapeState>=1 && modemEscapeState<=3 && b==ModemData.reg[REG_ESC] ) modemEscapeState++; else modemEscapeState=0; // wait a short time to see if another character is coming in so we // can send multi-character (escape) sequences in the same packet // some BBSs don't recognize the sequence if there is too much delay while( !SWSerial.available() && millis()-prevCharTime < millisPerChar ); } // if not sending in binary mode then a stand-alone CR (without LF) must be followd by NUL if( ModemData.reg[REG_TELNET] && !modemTelnetState.sendBinary && buf[n-1] == 0x0d && !SWSerial.available() ) buf[n++] = 0; modemClient.write(buf, n); } } void relayTelnetData() { if (telnetClient.available()) { //get data from the telnet client and push it to the UART unsigned long t = millis(); while(telnetClient.available() && millis()-t < 100) { uint8_t b = telnetClient.read(); if( !handleTelnetProtocol(b, telnetClient, clientTelnetState) ) SWSerial.write(b); } } if( millis() > prevCharTime + 20*ModemData.reg[REG_GUARDTIME] ) { if( modemEscapeState==0 ) modemEscapeState = 1; else if( modemEscapeState==4 ) { // received [1 second pause] +++ [1 second pause] // => switch to command mode modemCommandMode = true; printModemResult(E_OK); } } //check UART for data if( SWSerial.available() ) { uint8_t buf[128]; int n = 0, millisPerChar = 1000 / (ModemData.baud / (1+ModemData.bits+ModemData.stopbits))+1; unsigned long t, startTime = millis(); if( millisPerChar<5 ) millisPerChar = 5; while( SWSerial.available() && n =1 && modemEscapeState<=3 && b==ModemData.reg[REG_ESC] ) modemEscapeState++; else modemEscapeState=0; // wait a short time to see if another character is coming in so we // can send multi-character (escape) sequences in the same packet t = millis(); while( !SWSerial.available() && millis()-t < millisPerChar ); } // push UART data to all connected telnet clients if( !ModemData.reg[REG_TELNET] || clientTelnetState.sendBinary ) telnetClient.write(buf, n); else { // if sending in telnet non-binary mode then a stand-alone CR (without LF) must be followd by NUL uint8_t buf2[sizeof(buf)*2]; int j, m = 0; for(j=0; j =n-1 || buf[j+1]!=0x0a) ) buf2[m++] = 0; } telnetClient.write(buf2, m); } } } void loop() { if( modemClient && modemClient.connected() ) { // modem is connected. if telnet server has new client then reject if( server.available() ) server.available().stop(); // only relay data if not in command mode if( !modemCommandMode ) relayModemData(); } else if( telnetClient && telnetClient.connected() ) { // modem is connected. if telnet server has new client then reject if( server.available() && server.available() != telnetClient ) server.available().stop(); // only relay data if not in command mode if( !modemCommandMode ) relayTelnetData(); } else { // check whether connection to modem client was lost if( !modemCommandMode ) { if( modemClient ) modemClient.stop(); if( telnetClient ) telnetClient.stop(); digitalWrite(DCD_PIN, LOW); modemCommandMode = true; ModemData.reg[REG_CURLINESPEED] = 0; printModemResult(E_NOCARRIER); } // check if there are any new telnet clients if( server.available() ) { if( millis()-prevRingTime > RING_MILLIS ) { if( ModemData.reg[1] >= 10 ) { // failsafe, after 10 rings we are not going to answer... server.available().stop(); prevRingTime = 0; ModemData.reg[1] = 0; } else { printModemResult(E_RING); prevRingTime = millis(); ModemData.reg[1]++; } } if( ModemData.reg[0] != 0 && ModemData.reg[1] >= ModemData.reg[0] ) { // force at least 1 second before responding delay(1000); telnetClient = server.accept(); int i = getConnectStatus(); printModemResult(i); digitalWrite(DCD_PIN, HIGH); resetTelnetState(clientTelnetState); modemEscapeState=0; modemCommandMode = false; } } else { prevRingTime = 0; ModemData.reg[1] = 0; } } if( modemCommandMode ) { handleModemCommand(); } }

| 품명/모델명 | [상세설명참조] | ||
|---|---|---|---|
| 인증유형/인증번호 | 해당없음 | ||
| 정격전압/소비전력 | [상세설명참조] | ||
| 제조년월 | [상세설명참조] | ||
| 제조자/수입품여부/수입자 | [상세설명참조] | ||
| 제조국 | [상세설명참조] | ||
| 크기/무게 | [상세설명참조] | ||
| 주요 사양 | [상세설명참조] | ||
| 품질보증기준 | [상세설명참조] | ||
| A/S 책임자와 전화번호 | [상세설명참조] | ||
상품이 장바구니에 담겼습니다.
바로 확인하시겠습니까?