‏הצגת רשומות עם תוויות IC. הצג את כל הרשומות
‏הצגת רשומות עם תוויות IC. הצג את כל הרשומות

יום שישי, 17 בינואר 2014

Arduino And EEPROM


שנה חדשה נפתחה בבלוג, היא עמוסה באתגרים חדשים את זה אני יכול להבטיח לכם, את המאמר הראשון השנה החלטתי להקדיש לכוכב מהשנה שעברה, הפעם נתעסק בכיצד ניתן להרחיב את הזיכרון המוגבל ב Arduino שהוא 32K בלבד.

דרישות

  • Arduino Uno
  • 24LC256 EEPROM
  • Wires
  • Breadboard




EEPROM - Electrically Erasable Programmable Read-Only Memory

אין ספק שהשם מפוצץ אבל בסופו של דבר מדובר ביחידת זיכרון שמאפשרת לשמור על המידע גם כאשר המכשיר כבוי, הרכיב שבחרתי עליו להדגים הוא 24LC256 שמאוד נפוץ במחיר 2 $ בלבד מאפשר לנו להרחיב את הזיכרון בעוד 256K ,הוא אינו נדיף בניגוד ל Ram ובנוסף הכתיבה והקריאה הן ברמת Bit בודד בניגוד לזיכרון Flash שלצורך שינוי ביט אחד יש לקרוא בלוק של מידע ,לטעון אותו לזיכרון ה Ram, לעשות את השינוי ולכתוב בחזרה ל Flash מה שהופך את העסק למסורבל אבל חיוני מאוד למידע בנפחים גדולים.

256K של זיכרון לא נדיף
הרגליים האנלוגיות (A5, A4) ב Arduino Uno מאפשרות לעבוד בתקשורת I2C Inter-Integrated Circuit שדומה מאוד ל SPI שראינו במאמר Arduino and MicroSD ההבדל העיקרי הוא שב SPI עבור כל רכיב נצטרך רגל אחת מה Arduino לעומת I2C שבו כל הרכיבים מתחברים לאותן כניסות בלוח ובקלות ניתן להוסיף עוד רכיבים, מדובר על 2 רגליים שבעזרתן מייצרים Bus הרגל הראשונה היא השעון, והשניה ל Data, לכל רכיב יש כתובת ייחודית שדרכה מתחברים בעזרת הממשק.

המון חיבורים עם 2 רגליים בלבד

קוד

החלטתי לתת דוגמה קצת יותר מורכבת מאשר כתיבה וקריאה של ערך בודד אלא לכתוב ולקרוא מחרוזות, ניתן לכתוב ולקרוא  16bytes  בלבד בכל פעם לכן יש להתקדם בכתובות בזיכרון בעזרת חלוקה ל Pages. 

#include <Wire.h>

//unique address for the eeprom 24LC256
#define eeprom1 0x50 
#define readblock 100
#define pageblock 16

//size of the message
unsigned char length = 0;
//receive data buffer
unsigned char rdata[readblock];

 
void setup(void)
{
  //example of parsable string
  unsigned char str_data[]={"{message:this is working! using EEPROM}\n"};

  Serial.begin(9600);

  //Active I2C interface
  Wire.begin();

  //writing  data to 24LC256
   writeData(str_data);
}

 void loop(){

    Serial.println("DATA READ");
 
    //reading data to 24LC256 
    readData(rdata,readblock);
    Serial.write(rdata,readblock);

    delay(1000);
}


void writeData( unsigned char * str_data)
{

  unsigned char pages = 0;
  unsigned char offset = 0;
  unsigned char index = 0;
  unsigned char counter = 0;

  //get the length of data
  length = getStrLength(str_data);
  //get the number of page to write
  pages = length / pageblock;

  //make the magic
  for(index = 0; index <= pages;index++)
  {
       //connecting to the device
       Wire.beginTransmission(eeprom1);
 
       //set the position of writing,
       Wire.write((int)((offset) >> 8));   //MSB -  Most significant bit
       Wire.write((int)((offset) & 0xFF)); // LSB - Least significant bit
     
       //total bytes writed to jump the next page address
       unsigned char i= 0;
     
       for(i= 0; i < pageblock;i++)
        {
                //writing the char to the memory unit.
                Wire.write((byte) str_data[counter]);
 
                //if counter equal data length quit!
                if(counter == length)
                      break;
                   
                 //increment the total counter of length
                 counter++;                
        }
   
       //end I2C transmission
        Wire.endTransmission();
     
        //move offset to the next page  
        offset += i;
     
        //give it some time...
        delay(10);
     
  }

}

 void readData(unsigned char* data, unsigned int length)
 {
 
   unsigned char offset = 0;
   unsigned char counter = 0;
 
   //start reading pages until new line break
  while(true)
  {
     //total bytes writed to jump the next page address 
     unsigned char i=0;
      Wire.beginTransmission(eeprom1);
   
      //set position of reading
      Wire.write((int)(offset >> 8));   //MSB -  Most significant bit
      Wire.write((int)(offset & 0xFF)); //LSB - Least significant bit
   
     //end I2C transmission
      Wire.endTransmission();

       //request data from device
      Wire.requestFrom(eeprom1,length);

      while(Wire.available())
      {
          //write char to position data
          data[counter] = Wire.read();
       
          //end of message!
          if(data[counter] == '\n')
          {
              return;
          }
       
         i++;
         counter++;
     }
   
     offset+=i;
     delay(10);
  }
}

 //get the length from chars array
 unsigned char getStrLength(unsigned char * data)
 {
   unsigned char str_len=0;
    do{ str_len++; } while(data[str_len]);
    return str_len;
 }



מבנה סופי



סיכום

אפשרות הרחבת הזיכרון מאפשרת  לשמור מידע יעודי עבור התוכניות שלנו ועדיין להשאיר מספיק מקום לקוד ב Arduino, החיבור עצמו פשוט ומאפשר לתפעל מספר רכיבים מבלי לבזבז רגליים, ממשק I2C נפוץ מאוד ויש בו שימוש רחב במוצרים רבים לכן חשוב להכיר אותו.

שנה חמישית, ואו!


יום שישי, 19 ביולי 2013

Motor Control Guide



עשינו דרך ארוכה עם Arduino ועדיין יש בו אינסוף אפשרויות, הפעם נראה כיצד ניתן לשלוט במנועים בעזרת H Bridge , נפתח לנו עולם חדש שמאפשר לבצע תנועה מהירה ומדוייקת בעזרת מנועי DC פשוטים שנמצאים כמעט בכל מקום, עם הזמן המנועים האלה קיבלו שמות מפוצצים כמו Servo, Steeper Motor, Robot Motor ועוד.

L293D

במנועי ה DC יש סה"כ 2 כניסות עבור ה Voltage וה Ground ואין לנו אפשרות לקבוע את כיוון הסיבוב של המנוע אלא אם אנחנו מחליפים בן החיבורים ושלא נדבר על לשלוט במהירות, בעזרת H Bridge ניתן לקבוע את כיוון סיבוב המנוע ובעזרת PWM לקבוע את המהירות שלו, נשתמש בג'וק L293D שמאפשר לחבר אליו 2 מנועים ולשלוט על אופן הסיבוב בעזרת ה Arduino.

חיבור מנוע DC בודד


PWM - Pulse Width Modulation

גרסת Arduino UNO מגיעה עם 6 כניסות המוגדרות כ PWM  (הסימון ~ על הלוח) , ניתן לקבוע את כמות ה Voltage שיעבור ביציאה ע"פ הרעיון של Duty Cycle, בעזרת שינוי המתח ניתן לשלוט במהירות המנוע, לקבוע את חוזק תאורת ה LED ובכלל להעביר מידע לפי עוצמת המתח, אם עד עכשיו הגדרנו יציאות פשוטות כ HIGH ו LOW כעת יש לנו טווח פעולה מ 0 עד 255 שמאפשר לנו לשחק עם עוצמת המתח.



דרישות

  • Arduino Uno
  • L293 H Bridge
  • DC Motor 5V
  • LED
  •  Resistors 330 Ohm
  • Wires




מבנה סופי




קוד

//input of the L293D for left DC motor
int input_left[] = {5, 6};
int led = 3;

void setup()
{
  pinMode(input_left[0], OUTPUT);
   pinMode(input_left[1], OUTPUT);
   pinMode(led, OUTPUT);
}

void loop()
{
  for(int i =0; i< 255; i++)
  {
      analogWrite (led,i);
      analogWrite (input_left[0],i);
       digitalWrite(input_left[1], LOW); 
       delay(15);
  }
  
    for(int i =255; i> 0; i--)
  {
      analogWrite (led,i);
      analogWrite (input_left[0],i);
       digitalWrite(input_left[1], LOW); 
       delay(15);
  }
  delay(100);
  
  //change motor direction
  for(int i =0; i< 255; i++)
  {
      analogWrite (led,i);
      analogWrite (input_left[1],i);
       digitalWrite(input_left[0], LOW); 
       delay(15);
  }
  
    for(int i =255; i> 0; i--)
  {
      analogWrite (led,i);
      analogWrite (input_left[1],i);
       digitalWrite(input_left[0], LOW); 
       delay(15);
  }
  

  delay(100);
}

סרט דוגמה




סיכום

מנועים מאפשרים לנו להסתובב במרחב ובעזרת המאמרים הקודמים בנושא אפשר להתחיל לבנות את הרובוט הראשון שלנו.

ההמשך יבוא!

יום שבת, 21 ביולי 2012

Arduino Shift Register Guide



ל Arduino יש סה"כ 14 כניסות \ יציאות דיגיטליות שעלולות להיגמר לנו מהר מאוד, מסכים ו Leds עלולים "לשתות" לנו את כל הכניסות\ היציאות ובעצם להגביל אותנו לכמות הרכיבים שנוכל לחבר, כאן ה Shift Registers נכנסים לתמונה ומאפשרים לנו להרחיב את כמות הכניסות \ יציאות ולנהל אותם בעזרת ה Arduino.

דרישות:

  • Arduino Uno
  • Arduino Prototype Shield
  • 74HC595N Shift Register 
  • Wires



74HC595N - Shifit Register

מוני הזזה נפוצים מאוד באלקטרוניקה , מדובר על מעגל לוגי ששומר מידע במערך תאים שכל תא בגודל של אחד ביט, ומאפשר לנו להעביר את המידע באופן טורי ( Serial) ומקבילי (Parallel), הוא מתמלא בכל פעימת שעון של המעבד, כל ביט חדש שנכנס מעלה את מיקום הביט שנכנס לפניו במערך כפי שניתן לראות בדוגמה:


מדובר ב"ג'וק" עם 16 רגליים שמאפשר לנו להגדיל את כמות I\Os  הדיגיטלים עבור ה Arduino, בעזרתו ניתן להוסיף עוד 8 רגליים ולשלם על 3 רגליים בלבד ב Arduino, ניתן לשרשר קבוצה של Shift Registers ביחד.




מפת רגליים:



QA - QH
שמונה רגליים חדשות לשליטה, QH היא רגל מיוחדת, ודרכה משרשרים Shift Register נוסף.

SER
מכיל את המידע עבור התא הבא שהולך להיכנס.

SRCLK
כשנעביר HIGH הוא יכניס את התא למערך.

RCLK
כשנעביר High נפעיל \ נכבה את הרגליים (QA-QH) ע"פ המערך.

SRCLR
מאפס את ה Shifit Register

OE
מאפשר להתחבר לרגליים (QA-QH) מופעל כאשר עובר בו GND.


מבנה סופי




קוד:

int SER_Pin = 10;
int RCLK_Pin = 9;
int SRCLK_Pin = 8;

#define number_of_74hc595s 1 
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

void setup(){
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);
  
  clearRegisters();
  writeRegisters();
}               

//write the register array items to low
void clearRegisters(){
  for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers[i] = LOW;
  }

//write values of the registers
void writeRegisters(){
  
  digitalWrite(RCLK_Pin, LOW);

  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);
    
    //get the register value from the Register Array
    int val = registers[i];

    //write the pin value to the SER Register
    digitalWrite(SER_Pin, val);
    
    //shift the register
    digitalWrite(SRCLK_Pin, HIGH);

  }
  //set the pins by the shifted registers
  digitalWrite(RCLK_Pin, HIGH);

}

//set value of the pin by index value
void setRegisterPin(int index, int value){
  registers[index] = value;
}

void loop(){

  setRegisterPin(1, HIGH);
  setRegisterPin(2, HIGH);
  setRegisterPin(3, HIGH);
  setRegisterPin(4, HIGH);
  setRegisterPin(5, HIGH);
  setRegisterPin(6, HIGH);
  setRegisterPin(7, HIGH);

  writeRegisters();
  delay(1000);
  
  setRegisterPin(1, LOW);
  setRegisterPin(2, LOW);
  setRegisterPin(3, LOW);
  setRegisterPin(4, LOW);
  setRegisterPin(5, LOW);
  setRegisterPin(6, LOW);
  setRegisterPin(7, LOW);
 writeRegisters();
   delay(1000);
}

סיכום:
עכשיו שום דבר לא יכול להגביל אותנו ובעזרת Arduino בודד ניתן להתממשק למספר גדול של כניסות \ יציאות דיגיטליות ולהפוך את הפרויקטים שלנו ליותר מורכבים.

תרחיב אותו!