آردوینو آردوینو Arduino Uno آموزش آردوینو پروژه های آردوینو

آموزش ساخت ساعت دیجیتال شنی با آردوینو و دات ماتریس ۸*۸ و ماژول شتاب سنج

Arduino-hourglass--digispark-
نوشته شده توسط امین زادخدمت

ساعت انواع مختلفی دارد. از قدیم در زندگی انسان‌ها به عنوان یکی از مهم‌ترین موارد در مبادلات و زندگی روزمره کاربرد داشته است. یکی از انواع قدیمی و باستانی ساعت، مدل ساعت شنی می‌باشد. این ساعت از دو محفظه به هم متصل تشکیل شده است. در یکی شن و در دیگری هوا قرار گرفته است. با چرخاندن ساعت شنی، شن‌ها از مخزن بالایی به سمت مخزن پایینی حرکت می‌کنند. بسته به حجم ظرف و ابعاد آن و میزان شن موجود در آن، در کنار حفره‌ای که بین دو محفظه قرار گرفته است، مدت زمان مشخصی را تعیین می‌کند. حس این ساعت‌ها به عنوان یک شمارنده معکوس بسیار جذاب است. در این پست روش ساخت ساعت شنی دیجییتالی را آموزش خواهم داد. در ادامه این آموزش با مرجع تخصصی آردوینو به زبان فارسی، دیجی اسپارک همراه باشید.

پروژه ساخت ساعت شنی با آردوینو و دات ماتریس - digispark

 


عملکرد ساعت شنی


در این پروژه ال ای دی های دات ماتریس توسط یک ماژول شتاب سنج کنترل می‌شوند. به این صورت که شتاب‌های حرکتی، شوک‌های مکانیکی و لرزش در این سنسور قابل اندازه‌گیری در سه محور X ، Y و Z می‌باشند. این سنسور برای هر محور یک خروجی با ولتاژ آنالوگ دارد. این خروجی با شتاب اندازه گیری شده رابطه مستقیم دارد. میکروکنترلر قابلیت این داده های آنالوگ گرفته شده از سنسور را توسط مبدل ADC ( آنالوگ به دیجیتال ) به دیجیتال تبدیل کرده وال ای دی های ماژول های دات ماتریس را به این ترتیب کنترل کند.

 

ماژول دات ماتریس تراشه MAX7219

این ماژول دارای ۸*۸ نقطه نورانی قابل کنترل می‌باشد و دارای ۳ کانال ارتباطی دیتا و دو کانال ارتباطی تغذیه می‌باشد. با استفاده از پروتکل ارتباطی SPI ارتباط بین ماژول و آردوینو فراهم می‌شود. برای برنامه نویسی از کتابخانه LedControl استفاده می‌کنیم.

ماژول شتاب سنج ۳ محوره ADXL335

ماژول ADXL335 یک سنسور شتاب سنج ۳ محور MEMS، با نویز و توان مصرفی بسیار پایین بوده ( تنها ۳۲۰ میکرو آمپر) و خروجی ولتاژ با حالت دهی سیگنال است. این سنسور میتواند شتابهای استاتیک گرانش با حداقل ±۳ g مانند کاربردهای زاویه سنجی را اندازه گیری کند. و همچنین شتابهای دینامیک مانند شتابهای حرکتی، شوکهای مکانیکی و لرزش در این سنسور قابل اندازه گیری است.

 

 


اتصالات مدار ساعت شنی آردوینو


اتصالات دات ماتریس

پایه Vcc : پایه ۵ ولت آردوینو

پایه GND : پایه GND آردوینو

پایه DIN : پایه ۱۲ آردوینو

پایه CS : پایه ۱۰ آردوینو

پایه CLK : پایه ۱۱ آردوینو

 

اتصالات شتاب سنج

پایه Vcc : پایه ۳٫۳ ولت آردوینو

پایه GND : پایه GND آردوینو

پایه X-out : پایه GND آردوینو

پایه Y-out : پایه GND آردوینو

 

اتصالات پروژه ساخت ساعت شنی با آردوینو و دات ماتریس - digispark

 


فراخوانی کتابخانه آردوینو


برای برنامه نویسی این پروژه نیاز به فراخوانی کتابخانه های HCMAX7219 و  ADXL335 داریم.

 


کدهای مدار ساعت شنی آردوینو


کدهای زیر را کپی کرده و در نرم افزار آردوینو قرار دهید. اگر روش استفاده از آردوینو IDE را نمی‌دانید؛ به پست آموزش کار با برد آردوینو Arduino و نصب نرم افزار Arduino IDE مراجعه کنید.

 

#include <math.h>
#include <LedControl.h>
#include "binary.h";

const int x_out = A3;
const int y_out = A2;
const int z_out = A1;

const int x_range_low = 230;
const int x_range_high = 430;

const int y_range_low = 230;
const int y_range_high = 430;
const int x_range_mid = (x_range_high + x_range_low) / 2;
const int y_range_mid = (y_range_high + y_range_low) / 2;


const int max_x = 0;
const int min_x = 300;
const int max_y = 0;
const int min_y = 300;

const int D_NORTH = 1;
const int D_NE = 2;
const int D_EAST = 3;
const int D_SE = 4;
const int D_SOUTH = 5; 
const int D_SW = 6;
const int D_WEST = 7;
const int D_NW = 8;
int quadrant;

const long interval = 1000;
long previousMillis = 0; 
unsigned long currentMillis;

const int random_scale = 5;
int random_score = 2;

/*
 pin 12 : DataIn 
 pin 11 : CLK 
 pin 10 : LOAD 
 */
const int number_devices = 2;
LedControl lc=LedControl(12, 11, 10, number_devices);

byte board[2][8] = {
  {
    B11111111,
    B11111111,
    B11111111,
    B11100111,
    B11100111,
    B11111111,
    B11111111,
    B11111111
  },{
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000
  }
};


void setup() {
  
  for(int i=0; i < number_devices; i++) {
    lc.shutdown(i, false); 
    lc.setIntensity(i, 8);
    lc.clearDisplay(i);
  } 

  Serial.begin(9600); 
  
  test_leds();
}

void test_leds(){
  Serial.print("start test\n");
  for (int h=0; h < number_devices; h++){
    for (int i=0; i < 8; i++){
      for (int j=0; j < 8; j++){
        lc.setLed(h, i, j, true);
        delay(10);
        lc.setLed(h, i, j, false);
      }
    }
  }
  Serial.print("end test\n");
}

boolean is_empty(int b, int row, int col){
  return bit_read(b, row, col) == 0;
}

int bit_read(int b, int row, int col){
  if(col > 7 || col < 0 || row > 7 || row < 0)
    return 1;
  return bitRead(board[b][row], 7-col);
}

void bit_swap(int from_b, int from_row, int from_col, int b, int row, int col){
  if (from_col >= 0 && from_col <= 7 && from_row >= 0 && from_row <= 7){
    bitClear(board[from_b][from_row], 7-from_col);
    if (from_b != b || from_row != row)  // draw it if we need to
      lc.setRow(from_b, from_row, board[from_b][from_row]);
  }
  if (col >= 0 && col <= 7 && row >= 0 && row <= 7){
    bitSet(board[b][row], 7-col);
    lc.setRow(b, row, board[b][row]);
  }
}


void process_boards(){
  for (int b=0; b < number_devices; b++){
    for (int row=0; row < 8; row++){
      for (int col=0; col < 8; col++){
        
        if(bit_read(b, row, col) == 1){
        


          
          if (quadrant == D_NORTH){
        
            if(b==0 && row==7 && col==7 && is_empty(1, 0, 0)){
              if(currentMillis - previousMillis > interval) {
                  previousMillis = currentMillis;   

                  bit_swap(b, row, col, 1, 0, 0);
              }
            }else if(is_empty(b, row+1, col+1)){              
              bit_swap(b, row, col, b, row+1, col+1);
            }else if(is_empty(b, row+1, col)){
              bit_swap(b, row, col, b, row+1, col);
            }else if(is_empty(b, row, col+1)){
              bit_swap(b, row, col, b, row, col+1);
            }
            
          }else if (quadrant == D_NE){
            if(is_empty(b, row+1, col)){
              bit_swap(b, row, col, b, row+1, col);
            } 
            else if (random(1,random_scale) == random_score){
              if(is_empty(b, row+1, col-1)){
                bit_swap(b, row, col, b, row+1, col-1);
              }else if (is_empty(b, row+1, col+1)){
                bit_swap(b, row, col, b, row+1, col+1);
              }
            }
            
          }else if (quadrant == D_EAST){
            if(is_empty(b, row+1, col-1)){
              bit_swap(b, row, col, b, row+1, col-1);
            }else if(is_empty(b, row, col-1)){
              bit_swap(b, row, col, b, row, col-1);
            }else if(is_empty(b, row+1, col)){
              bit_swap(b, row, col, b, row+1, col);
            }
            
          }else if (quadrant == D_SE){
            if(is_empty(b, row, col-1)){
              bit_swap(b, row, col, b, row, col-1);
            } 
            else if (random(1,random_scale) == random_score){
              if(is_empty(b, row-1, col-1)){
                bit_swap(b, row, col, b, row-1, col-1);
              }else if (is_empty(b, row+1, col-1)){
                bit_swap(b, row, col, b, row+1, col-1);
              }
            }
            
          }else if (quadrant == D_SOUTH){
              
            if(b==1 && row==0 && col==0 && is_empty(0, 7, 7)){
               if(currentMillis - previousMillis > interval) {
                  previousMillis = currentMillis;   
                  
                  bit_swap(b, row, col, 0, 7, 7);
               }
            }else if(is_empty(b, row-1, col-1)){
              bit_swap(b, row, col, b, row-1, col-1);
            }else if(is_empty(b, row-1, col)){
              bit_swap(b, row, col, b, row-1, col);
            }else if(is_empty(b, row, col-1)){
              bit_swap(b, row, col, b, row, col-1);
            }
            
          }else if (quadrant == D_SW){
            if(is_empty(b, row-1, col)){
              bit_swap(b, row, col, b, row-1, col);
            }
            else if (random(1, random_scale) == random_score){
              if(is_empty(b, row-1, col+1)){
                bit_swap(b, row, col, b, row-1, col+1);
              }else if (is_empty(b, row-1, col-1)){
                bit_swap(b, row, col, b, row-1, col-1);
              }
            }
            
          }else if (quadrant == D_WEST){
            if(is_empty(b, row-1, col+1)){
              bit_swap(b, row, col, b, row-1, col+1);
            }else if(is_empty(b, row, col+1)){
              bit_swap(b, row, col, b, row, col+1);
            }else if(is_empty(b, row-1, col)){
              bit_swap(b, row, col, b, row-1, col);
            }
            
          }else if (quadrant == D_NW){
            if(is_empty(b, row, col+1)){
              bit_swap(b, row, col, b, row, col+1);
            } 
            else if (random(1,random_scale) == random_score){
              if(is_empty(b, row+1, col+1)){
                bit_swap(b, row, col, b, row+1, col+1);
              }else if (is_empty(b, row-1, col+1)){
                bit_swap(b, row, col, b, row-1, col+1);
              }
            }
          }


          
        }
      }
    }
  }
}


void loop() {
   
  int x_adc_value, y_adc_value, z_adc_value, theta;

  currentMillis = millis();

  x_adc_value = analogRead(x_out) - x_range_mid;
  y_adc_value = analogRead(y_out) - y_range_mid;
 
  
  theta = round( atan2 (y_adc_value, x_adc_value) * 180/3.14159265 );
  if(theta < 1) theta += 360;

 
  if(theta < 22.5 or theta > 337.5) quadrant = D_NORTH;
  else if(theta < 67.5)             quadrant = D_NW;
  else if(theta < 112.5)            quadrant = D_WEST;
  else if(theta < 157.5)            quadrant = D_SW;
  else if(theta < 202.5)            quadrant = D_SOUTH;
  else if(theta < 247.5)            quadrant = D_SE;
  else if(theta < 292.5)            quadrant = D_EAST;
  else                              quadrant = D_NE;

  process_boards();
  
  delay(20);
}

 

 


ساخت جعبه ساعت شنی


با استفاده از فایل کرول زیر میتوانید با برش لیزری یک جعبه و قاب برای ساعت شنی خود بسازید. یا اینکه با استفاده از اندازه های داده شده با استفاده از تخته سه لایه و اره مویی آن را بسازید.

فایل

ساخت جعبه برای اتصالات پروژه ساخت ساعت شنی با آردوینو و دات ماتریس - digispark

 

 


تغذیه مدار ساعت شنی آردوینو


با استفاده از یک منبع تغذیه DC (آداپتور) ۹ یا ۱۲ ولت میتوانید ساعت شنی را راه اندازی کنید یا اینکه برای زیباتر شدن کار از باطری های قابل شارژ و ماژول های شارژر استفاده کنید .

 


وسایل مورد نیاز


 برد آردوینو Arduino UNO R3

۲عدد  ماژول دات ماتریس ۸×۸ با تراشه MAX7219

ماژول شتاب سنج سه محوره ADXL335

 

 

چنانچه در مراحل راه اندازی و انجام این پروژه با مشکل مواجه شدید، بدون هیچ نگرانی در انتهای همین پست، به صورت ثبت نظر سوالتان را مطرح کنید. من در سریع‌ترین زمان ممکن پاسخ رفع مشکل شما را خواهم داد. همچنین اگر ایرادی در کدها و یا مراحل اجرایی وجود دارند می‌توانید از همین طریق اطلاع رسانی کنید.

 


پروژه و دریافت بن ارسال رایگان


برای دریافت بن خرید از دانشجو کیت، کاربران بایستی با استفاده از وسایل این آموزش، پروژه را اجرا کرده و یا حتی مدار جدیدی تعریف کنید. سپس از اجرای کار فیلم گرفته و در شبکه‌های اجتماعی از جمله آپارات و اینستگرام، با هشتگ‌های دیجی_اسپارک   دانشجوکیت    digispark    daneshjookit منتشر کنند. سپس از طریق بخش نظرات در ادامه همین آموزش، جهت دریافت بن خرید ارسال رایگان به ارزش ۱۲۰۰۰ تومان از دانشجو کیت، لینک را زیر همین پست ارسال کنید.

 

در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی , از وبسایت دیجی اسپارک حمایت کنید.

 

درباره نویسنده

امین زادخدمت

تبادل نظر و رفع عیب با ثبت دیدگاه

۲۴ دیدگاه

  • سلام
    آموزش جالبی بود، لطفا ویدیو هم قرار بدید. من اینو میتونم با آردوینو پرو مینی هم انجام بدهم؟

    • ویدیو به زودی اضافه میشه
      اگه بخواهید از آردوینو پرو مینی استفاده کنید باید به این نکنه توجه کنید که پرو مینی در ۲ نوع ولتاژ کاری ۳.۳ ولت و ۵ ولت موجود است و اینکه ماژول دات ماتریس با ولتاژ ۵ ولت و ماژول adxl335 با ولتاژ ۳.۳ ولت تغذیه می شود با در نظر گرفتن این موضوع باید برد آردوینو مناسب را انتخاب کنید

  • با سلام
    ممنون از پست های خوبتون
    آیا با کج کردن مدار به طرفین، led ها هم به کنار منتقل میشن؟؟؟
    مثلا ساعت شنی رو که کج میکنیم شن ها به همون سمتی که کج شدن میان

  • سلام.خیلی ممنون بابت سایت خوب و جالبتون.
    یه سوال داشتم در موردسنسورشتاب سنج ADXL335 .این سنسور توی بازارخیلی گرونه .میخواستم ازتون خواهش کنم که کد برنامه با سنسور ADXL345 رو قراربدین چون ارزونتره. ممنون میشم اگه قراربدین.

  • سلام خسته نباشید
    ببخشید اندازه های لازم برای ساخت جعبه واضح نیست
    میشه فایل واضحشو آپلود کنید لطفا

  • سلام.ممنون بابت سایت خوبتون.
    ببخشید میشه همین کدو بدون سنسور هم قرار بدین یعنی خودش بریزه و دوباره پرشه و تکرار شه.
    مرسی

  • نحوه اتصال شتاب سنج به آردوینو در تصویر و متن یکی نیست.
    در متن پایه x,y شتاب سنج به GND ولی در تصویر به پایه های A2,A3 متصل شده است.

    • با سلام
      اتصالات را طبق کد برنامه انجام دهید.
      const int x_out = A3;
      const int y_out = A2;
      const int z_out = A1;

  • سلام وقت بخیر میشه اگر امکان داره الگوریتم حرکت ذره ها در تغییر جهت ها رو توضیح بدید چون بنده می خوام به زبان دیگری کد بزنم
    ممنون

  • سلام خشته نباشید
    من این پروژه رو بستم ولی فقط در یک جهت عمل میکند
    یعنی با برعکس کردن سنسور شتاب هیچ تغییری صورت نمیگیرد

      • شما در لینکی که خرید قطعات رو قرار دادید لینک فروش ستاب سنج ماژول ۳۴۵ هستش ولی کد قرار داده شده مربوط به ۳۳۵ هست. ما از طریق لینک خود شما خریداری کردیم و پس از خرید متوجه شدیم ۳۴۵ بوده. الان واقعا دچار مشکل هستیم لطفا بررسی بفرمایید و اگر قرار نیست انجام بشه بفرمایید ۳۳۵ تهیه کنیم!

  • همچنین فایل طراحی باکس در نرم افزار کورل رو هم قرار ندادید. عکس موجود در سایت واقعا کیفیت لازم برای بهره برداری رو نداره.

  • با سلام. لطفا فایل کورل یا عکس با کیفیت که ابعاد روش مشخص باشه رو ارائه بدید. ممنون میشم.

  • با سلام. برنامه فقط در یک جهت کار میکند! امکانش هست که اصلاح بفرمایید؟ یعنی با برعکس کردن ژیروسکوپ حرکت ساعت برعکس نمیشه.