제조공정
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
| ||||
|
이야기
이 프로젝트는 원래 Thingiverse의 Xpider였습니다. 그런 다음 Alex Glow의 아르키메데스를 말합니다. 그것은 내 마음을 날려 버렸어. 너무 싫었어요. 그래서 나는 스스로 로봇 동반자를 만드는 일을 해야 했다. 나는 내가 올빼미 유형이 아니라고 생각했고 나의 친숙한 사람이 특별하기를 원했습니다. 그러다가 거미, 사기꾼, 이야기의 신 아난시의 아프리카 이야기가 떠올랐다. 스토리라는 생각으로 봇을 디자인하기로 했고 그래서 Asi가 탄생했습니다(실제로는 Asi_v4, v1-3은 프로토타입).
어셈블리
원래 디자인은 Xpider였습니다. 그러나 나는 그것을 한 단계 더 끌어 올렸고 많은 것을 외부에서 편집했고 당신도 알다시피 땜질했습니다. 이것들은 인쇄해야 하는 대부분의 부품입니다.
조립은 꽤 자명하지만 어쨌든 여기에 몇 가지 사진이 있습니다.
그림>
전자 제품의 경우 일반적으로 머리의 위쪽이나 아래쪽에 둘 수 있지만(귀하의 호출) 서보는 그렇게 부착해야 합니다. 기어가 켜져 있는지 확인하십시오.
Asi는 Trinket과 Arduino Nano의 두 가지 마이크로 컨트롤러로 제어됩니다. Trinket은 임의의 간격으로 앞뒤로 회전하는 서보 덕분에 눈의 움직임을 제어합니다. Arduino Nano는 눈을 제어합니다. 그가 주위를 둘러보는 것도 무작위적이며 보통 사람들은 그가 그들을 보고 있다고 생각합니다.
그림> 그림>
참고로 저는 4x AA 배터리로 데이지 체인으로 연결된 두 개의 작은 브레드보드에 있습니다. (리튬 이온 배터리 3.7 200mAh를 사용할 수도 있습니다. 리튬 이온 배터리의 경우 어떤 이유로 작동하지 않는 경우가 있으므로 별도의 리튬 배터리 2개를 사용하여 동일한 온오프 스위치에 부착합니다. 모든 것이 한 번에 시작됩니다.)
머리는 내가 휴가 동안 얻은 크리스마스 구체입니다. 나는 한 발 물러서서 검은 색 스프레이 페인트로 가볍게 뿌렸다. 그런 다음 뜨거운 접착제를 가져다가 Asi의 목 부분에 붙이면 머리가 붐!
그림> 그림>
마지막으로 착용 방법입니다. 전기자 철사를 가져와서 Asi 바닥 부분 전체에 꿰어 배낭의 어깨에 메었습니다.
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">
#include//항상 LedControl 라이브러리를 포함해야 합니다.#include "LedControl.h"/* LetControl 객체를 생성하고 핀 연결을 정의합니다. 눈에는 2개의 MAX72XX가 있습니다. */#define PIN_EYES_DIN 12#define PIN_EYES_CS 11#define PIN_EYES_CLK 10LedControl lc =LedControl(PIN_EYES_DIN, PIN_EYES_CLK, PIN_EYES_CS, 2);// rotationbool rotateMatrix0 =false; // 0 행렬을 180도 회전합니다. degbool rotateMatrix1 =false; // 180도만큼 회전하는 현재 상태 저장// 퓨필 바이트 없이 안구 정의 eyeBall[8]={ B01111110, B11111111, B11111111, B11111111, B11111111, B11111111, B0110101; LEDsbyte eyeCurrent[8];int currentX;int currentY;int cntLoop =0;int cntEffect =0;// 최소 및 최대 위치#define MIN -2#define MAX 2// delays#define DELAY_BLINK 40// 마다 효과 수행 루프 반복 횟수, 0에서 비활성화#define EFFECT_ITERATION 4/* Arduino setup*/void setup() { // MAX72XX는 시작 시 절전 모드에 있으므로 웨이크업 호출을 수행해야 합니다. lc.shutdown(0,false); lc.shutdown(1,거짓); // 밝기를 낮게 설정 lc.setIntensity(0,1); lc.setIntensity(1,1); // 두 모듈 모두 지우기 lc.clearDisplay(0); lc.clearDisplay(1); // LED 테스트 // 세로줄 바이트 b =B10000000; for (int c=0; c<=7; c++) { for (int r=0; r<=7; r++) { setRow(0, r, b); setRow(1, r, b); } b =b>> 1; 지연(50); } // 전체 모듈 b =B11111111; (int r=0; r<=7; r++) { setRow(0, r, b); setRow(1, r, b); } 지연(500); // 두 모듈 모두 지우기 lc.clearDisplay(0); lc.clearDisplay(1); 지연(500); // 랜덤 시드 randomSeed(analogRead(0)); // 중심 눈, 미친듯이 깜박임 displayEyes(0, 0); 지연(2000); 깜박임 눈(참, 거짓); 깜박임(거짓, 참); delay(1000);}/* Arduino loop*/void loop() { // 임의의 위치로 이동하고 임의의 시간을 기다립니다. moveEyes(random(MIN, MAX + 1), random(MIN, MAX + 1), 50); 지연(무작위(5, 7) * 500); // 깜박임 시간? if (random(0, 5) ==0) { delay(500); 눈 깜박임(); 지연(500); } // 효과 시간? if (EFFECT_ITERATION> 0) { cntLoop++; if (cntLoop ==EFFECT_ITERATION) { cntLoop =0; if (cntEffect> 6) cntEffect =0; switch(cntEffect) { case 0:// 교차 눈 crossEyes(); 지연(1000); 부서지다; 사례 1:// 라운드 스핀 roundSpin(2); 지연(1000); 부서지다; 사례 2:// 미친 회전 crazySpin(2); 지연(1000); 부서지다; 사례 3:// meth 눈 methEyes(); 지연(1000); 부서지다; 사례 4:// 게으른 눈 lazyEye(); 지연(1000); 부서지다; 사례 5:// 미친 깜박임 깜박임 눈(true, false); 깜박임(거짓, 참); 지연(1000); 부서지다; 사례 6:// 글로우 glowEyes(3); 지연(1000); 부서지다; 기본값:중단; } cntEffect++; } }}/* 이 메서드는 두 눈을 모두 깜박입니다.*/void 깜박임Eyes(){ 깜박임(true, true);}/* 이 메서드는 제공된 매개변수에 따라 눈을 깜박입니다.*/void 깜박임Eyes(boolean blinkLeft, boolean blinkRight){ // 깜박임 ? if (!blinkLeft &&!blinkRight) return; // 눈꺼풀을 감습니다. for (int i=0; i<=3; i++) { if (blinkLeft) { setRow(0, i, 0); setRow(0, 7-i, 0); } if (blinkRight) { setRow(1, i, 0); setRow(1, 7-i, 0); } 지연(DELAY_BLINK); } // 눈꺼풀을 엽니다 for (int i=3; i>=0; i--) { if (blinkLeft) { setRow(0, i, eyeCurrent[i]); setRow(0, 7-i, eyeCurrent[7-i]); } if (blinkRight) { setRow(1, i, eyeCurrent[i]); setRow(1, 7-i, eyeCurrent[7-i]); } 지연(DELAY_BLINK); }}/* 이 메서드는 눈을 중앙 위치로 이동한 다음 가장자리를 감싸면서 수평으로 이동합니다.*/void crazySpin(int times){ if (times ==0) return; moveEyes(0, 0, 50); 지연(500); 바이트 행 =eyePupil; for (int t=0; t > 1; 행 =행 | B10000000; setRow(0, 3, 행); setRow(1, 3, 행); setRow(0, 4, 행); setRow(1, 4, 행); 지연(50); if (t ==0) 지연((5-i)*10); // 첫 번째 스크롤 시 지연 증가(속도 향상 효과) } // R에서 중심으로 회전 for (int i=0; i<5; i++) { row =row>> 1; if (i>=2) 행 =행 | B10000000; setRow(0, 3, 행); setRow(1, 3, 행); setRow(0, 4, 행); setRow(1, 4, 행); 지연(50); if (t ==(times-1)) 지연((i+1)*10); // 마지막 스크롤 시 지연 증가(느림 효과) } }}/* 이 메서드는 눈을 가립니다.*/void crossEyes(){ moveEyes(0, 0, 50); 지연(500); 바이트 눈동자R =eyePupil; 바이트 동공L =눈동공; // 동공을 함께 이동 for (int i=0; i<2; i++) { 동공 =동공>> 1; 동공R =동공R | B10000000; 동공 =동공 <<1; 동공 =동공 | B1; setRow(0, 3, 동공R); setRow(1, 3, 동공L); setRow(0, 4, 동공R); setRow(1, 4, 동공L); 지연(100); } 지연(2000); // 동공을 중앙으로 다시 이동 for (int i=0; i<2; i++) { 동공 =동공 <<1; 동공R =동공R | B1; 동공 =동공L>> 1; 동공 =동공 | B10000000; setRow(0, 3, 동공R); setRow(1, 3, 동공L); setRow(0, 4, 동공R); setRow(1, 4, 동공L); 지연(100); }}/* 이 메서드는 중심 위치에서 X, Y 값만큼 동공 오프셋이 있는 안구를 표시합니다. 유효한 X 및 Y 범위는 [MIN,MAX]입니다. 두 LED 모듈 모두 동일한 눈을 표시합니다.*/void displayEyes(int offsetX, int offsetY) { // 오프셋이 유효한 범위에 있는지 확인합니다. offsetX =getValidValue(offsetX); 오프셋Y =getValidValue(오프셋Y); // 동공 행에 대한 인덱스 계산(오프셋 Y 수행) int row1 =3 - offsetY; int row2 =4 - 오프셋 Y; // 동공 행 바이트를 정의합니다.pupilRow =eyePupil; // 오프셋 X를 수행합니다. // 비트 이동을 수행하고 새 비트를 1로 채웁니다. if (offsetX> 0) { for (int i=1; i<=offsetX; i++) { pupilRow =pupilRow>> 1; 동공 =동공 | B10000000; } } else if (offsetX <0) { for (int i=-1; i>=offsetX; i--) { 동공 =동공 <<1; 동공 =동공 | B1; } } // 눈동자 행은 1을 가질 수 없습니다. 여기서 eyeBall의 바이트는 0입니다. PupilRow1 =눈동자 Row &eyeBall[row1]; 바이트 눈동자Row2 =눈동자 및 눈볼[row2]; // LCD 매트릭스에 표시, eyeCurrent로 업데이트 for(int r=0; r<8; r++) { if (r ==row1) { setRow(0, r, 눈동자Row1); setRow(1, r, 동공1); 눈 현재[r] =눈동자 행1; } else if (r ==row2) { setRow(0, r, 눈동자Row2); setRow(1, r, 동공2); 눈 현재[r] =눈동자 행2; } else { setRow(0, r, eyeBall[r]); setRow(1, r, eyeBall[r]); eyeCurrent[r] =eyeBall[r]; } } // 현재 X 및 Y 업데이트 currentX =offsetX; currentY =offsetY;}/* 이 메서드는 제공된 좌표 값을 수정합니다.*/int getValidValue(int value){ if (value> MAX) return MAX; 그렇지 않으면 (값 =1; i--) { lc.setIntensity(0,i); lc.setIntensity(1,i); 지연(25); } 지연(150); }}/* 이 메서드는 눈을 가운데로 이동했다가 바깥쪽으로 이동했다가 다시 가운데로 이동합니다.*/void methEyes(){ moveEyes(0, 0, 50); 지연(500); 바이트 눈동자R =eyePupil; 바이트 동공L =눈동공; // 동공을 밖으로 이동 for (int i=0; i<2; i++) { 동공 =동공 <<1; 동공R =동공R | B1; 동공 =동공L>> 1; 동공 =동공 | B10000000; setRow(0, 3, 동공R); setRow(1, 3, 동공L); setRow(0, 4, 동공R); setRow(1, 4, 동공L); 지연(100); } 지연(2000); // 동공을 다시 중앙으로 이동 for (int i=0; i<2; i++) { 동공 =동공>> 1; 동공R =동공R | B10000000; 동공 =동공 <<1; 동공 =동공 | B1; setRow(0, 3, 동공R); setRow(1, 3, 동공L); setRow(0, 4, 동공R); setRow(1, 4, 동공L); 지연(100); }}/* 이 메서드는 두 눈을 현재 위치에서 새 위치로 이동합니다.*/void moveEyes(int newX, int newY, int stepDelay){ // 현재 위치를 시작 위치로 설정 int startX =currentX; 정수 시작Y =현재Y; // 유효하지 않은 새 XY 값 수정 newX =getValidValue(newX); newY =getValidValue(newY); // 단계 평가 int stepsX =abs(currentX - newX); int stepsY =abs(현재Y - 새Y); // 적어도 하나의 위치를 변경해야 함 if ((stepsX ==0) &&(stepsY ==0)) return; // 이동 방향 평가, 단계 수, XY 단계마다 변경, 이동 수행 int dirX =(newX>=currentX) ? 1:-1; int dirY =(newY>=현재Y) ? 1:-1; int 단계 =(단계 X> 단계 Y) ? 단계X :단계Y; int intX, intY; float changeX =(float)stepsX / (float)steps; float 변경Y =(float)stepsY / (float)steps; for (int i=1; i<=steps; i++) { intX =startX + round(changeX * i * dirX); intY =startY + round(changeY * i * dirY); displayEyes(intX, intY); 지연(단계지연); }}/* 이 메서드는 오른쪽 눈동자만 낮추고 올립니다.*/void lazyEye(){ moveEyes(0, 1, 50); 지연(500); // 왼쪽 아래 동공을 천천히 for (int i=0; i<3; i++) { setRow(1, i+2, eyeBall[i+2]); setRow(1, i+3, eyeBall[i+3] &eyePupil); setRow(1, i+4, eyeBall[i+4] &eyePupil); 지연(150); } 지연(1000); // 왼쪽 눈동자를 빠르게 올리기 for (int i=0; i<3; i++) { setRow(1, 4-i, eyeBall[4-i] &eyePupil); setRow(1, 5-i, eyeBall[5-i] &eyePupil); setRow(1, 6-i, eyeBall[6-i]); 지연(25); } }/* 이 메서드는 눈동자를 시계 방향으로 회전합니다.*/void roundSpin(int times){ if (times ==0) return; moveEyes(2, 0, 50); 지연(500); for (int i=0; i<번; i++) { displayEyes(2, -1); 지연(40); if (i==0) 지연(40); displayEyes(1, -2); 지연(40); if (i==0) 지연(30); displayEyes(0, -2); 지연(40); if (i==0) 지연(20); displayEyes(-1, -2); 지연(40);만약 (i==0) 지연(10); displayEyes(-2, -1); 지연(40); displayEyes(-2, 0); 지연(40); displayEyes(-2, 1); 지연(40);if (i==(배-1)) 지연(10); displayEyes(-1, 2); 지연(40);if (i==(배-1)) 지연(20); displayEyes(0, 2); 지연(40); if (i==(times-1)) 지연(30); displayEyes(1, 2); 지연(40); if (i==(times-1)) 지연(40); displayEyes(2, 1); 지연(40); if (i==(times-1)) 지연(50); displayEyes(2, 0); 지연(40); }}/* 이 메소드는 행렬 행에 값을 설정합니다. 필요한 경우 180 회전을 수행합니다.*/void setRow(int addr, int row, byte rowValue){ if (((addr ==0) &&(rotateMatrix0)) || (addr ==1 &&회전 매트릭스1)) { 행 =abs(행 - 7); rowValue =비트스왑(rowValue); } lc.setRow(addr, row, rowValue);}/* 바이트 단위의 역 비트 http://www.nrtm.org/index.php/2013/07/25/reverse-bits-in-a-byte/* /byte bitswap (byte x){ 바이트 결과; asm("mov __tmp_reg__, %[in] \n\t" "lsl __tmp_reg__ \n\t" /* 높은 비트를 캐리로 시프트 */ "ror %[out] \n\t" /* 캐리 __tmp_reg__를 로우로 회전 비트 (결국) */ "lsl __tmp_reg__ \n\t" /* 2 */ "ror %[out] \n\t" "lsl __tmp_reg__ \n\t" /* 3 */ "ror %[out] \ n\t" "lsl __tmp_reg__ \n\t" /* 4 */ "ror %[out] \n\t" "lsl __tmp_reg__ \n\t" /* 5 */ "ror %[out] \n\ t" "lsl __tmp_reg__ \n\t" /* 6 */ "ror %[out] \n\t" "lsl __tmp_reg__ \n\t" /* 7 */ "ror %[out] \n\t" "lsl __tmp_reg__ \n\t" /* 8 */ "ror %[out] \n\t" :[out] "=r" (결과) :[in] "r" (x)); 반환(결과);}
// Servo 매개변수입니다. 핀은 장신구에서 1 또는 4여야 합니다. 서보 위치는 // 원시 타이머/카운터 틱(1 틱 =0.128 밀리초)으로 지정됩니다. // 서보 펄스 타이밍은 일반적으로 1-2ms이지만 서보 간에 약간 다를 수 있으므로 이러한 제한을 조정해야 할 수도 있습니다. 현실과 일치합니다.#define SERVO_PIN 4 // 핀 1 또는 4는 Trinket에서 지원됩니다#define SERVO_MIN 4 // ~1ms 펄스#define SERVO_MAX 26 // ~2ms 펄스 Adafruit_TiCoServo 서보; void setup(void) {#if (F_CPU ==16000000L) // 16MHz Trinket은 정확한 타이밍을 위해 프리스케일을 설정해야 합니다. // 이것은 서보.attach() 전에 수행되어야 합니다! clock_prescale_set(clock_div_1);#endifservo.attach(SERVO_PIN); 핀모드(LED_PIN, 출력); digitalWrite(LED_PIN, HIGH);} uint32_t lastLookTime =0; // 마지막 헤드 턴 시간 void loop(void) { unsigned long t =millis(); // 현재 시간 // 마지막 머리 회전 이후 1/2초 이상 경과한 경우... if((t - lastLookTime)> 500) { if(random(10) ==0) { // 1- in-10 기회... // ...머리를 새로운 방향으로 무작위로 이동:서보.write(random(SERVO_MIN, SERVO_MAX)); 마지막보기 시간 =t; // 앞으로의 참조를 위해 헤드 턴 시간을 저장합니다. } } // 헤드 턴 검사와 관련이 없습니다. if(random(10) ==0) { // 10분의 1의 확률이 있습니다... // .. ."눈 깜박임":digitalWrite(LED_PIN, LOW); // LED 꺼짐 delay(random(50, 250)); // 임의의 짧은 순간 동안 digitalWrite(LED_PIN, HIGH); // 다시 ON } delay(100); // loop()를 초당 10회 정도 반복}섹션>
제조공정
이 튜토리얼에서는 Arduino hexapod를 구축하는 방법을 보여줍니다. 이름에서 알 수 있듯이 헥사포드에는 6개의 다리가 있지만 그 외에도 꼬리 또는 복부, 머리, 안테나, 하악 및 기능적인 눈도 있습니다. 이 모든 것이 헥사포드를 개미처럼 보이게 하므로 Arduino Ant Robot이라고도 부를 수 있습니다. 다음 비디오를 보거나 아래에 작성된 튜토리얼을 읽을 수 있습니다. 개요 로봇을 제어하기 위해 맞춤형 Android 애플리케이션을 만들었습니다. 앱에는 4개의 버튼이 있어 로봇에게 전진 또는 후진, 좌회전 또는 우
최근에 폰을 한동안 사용하다보면 쉽게 전원이 나가서 배터리를 새로 사려고 합니다. 타오바오 온라인 스토어에서 배터리를 검색해 보니 일반 배터리가 매우 비쌉니다. 예를 들어, iPhone의 배터리 비용은 약 86달러입니다. 소형 배터리가 왜 그렇게 비싼지 궁금하지 않을 수 없습니다. 그 답을 함께 알아봅시다. 리튬 배터리는 배터리, 전원 관리 시스템 및 포장으로 구성됩니다. . 따라서 리튬 배터리의 가격을 알고 싶다면 이 세 부분 각각의 비용을 분석해야 합니다. 배터리 셀 비용 셀은 양극과 음극을 포함하는 단일 단위를 나타냅니다