В данной статье пойдет речь о том, как я ограничил время просмотра телевизора для ребенка с помощью Arduino.

С некоторых пор меня стали не устраивать оценки ребенка в школе. На планшет и смартфон были установлены пароли, на ПК ограничено время использования, но остался телевизор. Прятать кабель каждый день надоело, да и не факт, что он уже не купил свой. В результате решил сделать устройство, которое бы ограничивало время просмотра ТВ, т.е. просто отключало бы 220В.

Для реализации своей идеи использовал:

1. Double Side Prototype PCB Tinned Universal Breadboard 2x8 cm 20mmx80mm FR4:
image

2. 5V One 1 Channel Relay Module Board Shield For PIC AVR DSP ARM MCU Arduino:
image

3. USB Nano V3.0 ATmega328 16M 5V Micro-controller CH340G board For Arduino:
image

4. Mifare RC522 Card Read Antenna RF Module RFID Reader IC Card Proximity Module:
image

5. White 3-5V 0.96" SPI Serial 128X64 OLED LCD LED Display Module for Arduino:
image

При включении устройства оно считывает информацию из EEPROM на наличие записанных карт (максимальное количество карт я ограничил в 6 штук). В EEPROM хранятся последние 4 байта UID'а карты переведенные в десятичный формат. Для чтения и записи в EEPROM использовал библиотеку EEPROM2.h.

Код
cardPresent = readCards();
boolean readCards() {
  cardPresent = false;
  for(int k = 0; k <6; k++) {
    EEPROM_read(k*6+4, time[k]);
    if(time[k] >= 0) {
      cardPresent = true;
      EEPROM_read(k*6, cards[k]);
      }
  }
  return cardPresent;
}


Для работы с модулем MFRC522 использовал библиотеку MFRC522.h. Считываем карты следующим образом:

Код
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup() {
  SPI.begin();			// Init SPI bus
  mfrc522.PCD_Init();		// Init MFRC522
void loop() {
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}

        String s = dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        mfrc522.PICC_HaltA(); //останавливаем считывание карты до того момента как ее уберут от считывателя (иначе функция dump_byte_array будет выполняться несколько раз, пока карту не уберут от считывателя).
        Serial.println(s);
}


В случае если карты отсутствуют в EEPROM первая приложенная карта назначается мастером и записывается в ячейку 0:

Код
    if(!cardPresent) { //если карт нет, то записать карту как мастер
      short master = 0;
      EEPROM_write(0, uiddec);
      EEPROM_write(4, master);
      message = "NEW MASTER";
      cardPresent = true;
      readCards();
    }


Вывод сообщений на монитор. Использовал библиотеку HCuOLED.h:

Код
/* Create an instance of the library (uncomment one of the lines below) */
//HCuOLED HCuOLED(SSD1307, SS_DI, DC_DI, RST_DI); // For SSD1307 displays (HCMODU0050 & HCMODU0052)
HCuOLED HCuOLED(SH1106, CS_DI, DC_DI, RST_DI); // For SH1106 displays (HCMODU0058 & HCMODU0059)
void setup() {
     HCuOLED.Reset();
}
void drawUid(char *s) {
        HCuOLED.Erase(0,16,120,32);
        HCuOLED.SetFont(MedProp_11pt);
        HCuOLED.Cursor(0,16);
        HCuOLED.Print(s);
        HCuOLED.Refresh();
}

void drawLong(long uid) {
        HCuOLED.Erase(0,33,120,48);
        HCuOLED.SetFont(MedProp_11pt);
        HCuOLED.Cursor(0,33);
        HCuOLED.Print(uid);
        HCuOLED.Refresh();
}

void drawCardTime(String s) {
  char mess[12];
  s.toCharArray(mess, 12);
  HCuOLED.Erase(0,49,120,80);
  HCuOLED.SetFont(MedProp_11pt);
  HCuOLED.Cursor(0,49);
  HCuOLED.Print(mess);
  HCuOLED.Refresh();
}


Теперь приведу код функции String dump_byte_array(byte *buffer, byte bufferSize). Она вызывается после считывания карты. Работа устройства реализована следующим образом:

1. Переводим последние 4 байта в десятичный формат и выводим на экран uid карты в обоих форматах, ищем совпадение uid'а с тем что мы считали из EEPROM:

Код
    String s;
    unsigned long uiddec = 0;
    unsigned long temp;
    char uid[8];
    for (byte m = (bufferSize > 4 ? (bufferSize - 4) : 0); m < bufferSize; m++) { //берем только последние 4 байта и переводим в десятичную систему
        unsigned long p = 1;
        for(int k = 0; k < bufferSize-m-1; k++) {
          p = p*256;
        }
        uiddec += p*buffer[m];
        s = s + (buffer[m] < 0x10 ? "0" : "");
        s = s + String(buffer[m], HEX);
    }
    s.toCharArray(uid, 8);
    drawUid(uid);
    drawLong(uiddec);
    message = "unknow";
    short currentCard = -1;
    for(int k = 0; k <6; k++) { //сравнимаем полученный uid с тем что хранится в массиве карт
      if((time[k] >=0) && (cards[k] == uiddec)) {
        currentCard = k;
      }
    }


2. Далее идет код в котором реализована логика устройства. В случае если карта известна, но она не мастер, то вызывается функция onRelay(Relay, currentCard), которая проверяет достаточно ли прошло времени для включения.

String onRelay(int relayPin, short card)
  String onRelay(int relayPin, short card) {
  String messa;
  if(time[card] == 0) { //мастер пришел
    offAllCards(); //выключить все карты
    messa = "master ON";
    digitalWrite(relayPin, LOW); //включить реле
  } else {
    if(!isOn[card]) { //если карта не включена
      unsigned long lastOn = (lastTime[card] == NULL ? 0 : lastTime[card]); //последнее включение карты 
      if((millis()-lastOn)/60000 > (freqOn - 1)) { //если последнее включение было раньше, чем разрешенная частота использования
        messa = "time:" + String(time[card]);
        lastTime[card] = someCardsIsOn() + time[card]*60000; //установить время последнего использования в максимальное время из действующих карт + разрешенное время
        isOn[card] = true; //пометить что это одна из действующих карт
        digitalWrite(relayPin, LOW); //включить реле
      } else { //сообщить когда снова можно будет пользоваться
        short waitminutes = freqOn - (millis()-lastOn)/60000; //сколько осталось минут до возможности включить
        messa = "Wait:" + String(waitminutes/60) + "h" + String(waitminutes%60)+ "m";
        //messa = String(waitminutes);
      }
    } else {
      messa = "Allready ON";
    }
  }
  return messa;
}

void offAllCards() {
  for(int k = 0; k < 10; k++) {
    isOn[k] = false;
  }
}
unsigned long someCardsIsOn() { //если какая-то карта уже активна, то время работы устройства увеличивается на время новой карты
  unsigned long maxtime = millis();
  for(int k = 0; k <6; k++) {
    if(isOn[k]&&(lastTime[k] > maxtime)) {
      maxtime = lastTime[k];
    }
  }
  return maxtime;
}


Код
   if(currentCard > 0) { //карта найдена, но она не мастер
      message = onRelay(Relay, currentCard);
    } else {
      if(currentCard == 0) { //приложили мастер, если новая карта приложена ранее, то записать ее в EEPROM, если нет, то сделать выход мастеру
        if(!masterPresent) {
          newCard = false;
          masterPresent = true;
          message = "master in";
          onRelay(Relay, currentCard);
        } else {
          if(newCard) {
            for(int k = 1; k < 6; k++) {
              if(time[k] < 0) {
                writeNewCard(newCardUid,k);
                //Serial.println("new card write to " + String(k));
                newCard = false;
                message = "card added";
                break;
              }
            }
          } else {
            masterPresent=false;
            offRelay(Relay);
            message = "master out";
          }
        }
      } else { //если время меньше 0, то неизвестная карта, если мастер есть, то добавить, если нет то сообщить, что карта неизвестна
        if(masterPresent) {
          newCard = true;
          newCardUid = uiddec;
          message = "confirm?";
        } else {message = "unknow";}
      }
    }
    if(!cardPresent) { //если карт нет, то записать карту как мастер
      short master = 0;
      EEPROM_write(0, uiddec);
      EEPROM_write(4, master);
      message = "NEW MASTER";
      cardPresent = true;
      readCards();
    }
    if(uiddec == 696374757) { //для сброса устройства есть специальная карта
      eraseCards();
      cardPresent = readCards();
      message = "ERASED";
    }
    drawCardTime(message); 
}
void eraseCards() {
  short master = -1;
  for(int t = 0; t < 40; t++) {
  EEPROM_write(t*2, master);}
  readCards();
  //Serial.println("Cards erased");
}
void writeNewCard(unsigned long uid, int k) {
  short time = 30;
  EEPROM_write(k*6, uid);
  EEPROM_write(k*6+4, time);
  readCards();
}


Теперь не забудем отключить устройство когда закончится время, для этого в самое начало функции loop() добавим следующий код:

Код
    if((millis()/10000)%2 ^ i) { //check each 10 seconds
      i = !i;
      if(!masterPresent) {
        if(millis() > (someCardsIsOn()-1000)) {
          offRelay(Relay);
          message = "Time over";
        } else {
          message = "Remain:" + String((someCardsIsOn() - millis())/60000+1);
          Serial.println(message);
        }
        drawCardTime(message);
        HCuOLED.Refresh();
      }
    }


Код скетча целиком:

Код скетча целиком
/*
 * Typical pin layout used:
 * -----------------------------------------------------------------------------------------
 *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      10            53        D10        10               10
 * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
 */

#include <SPI.h>
#include <MFRC522.h>
#include <HCuOLED.h>
#include <EEPROM2.h>

#define RST_PIN		6		// 
#define SS_PIN		7		//

/* Digital pin number for the displays chip select pin */
#define CS_DI 10
/* Digital pin number for the displays data/command pin */
#define DC_DI 9
/* Digital pin number for the displays reset pin */
#define RST_DI 8
#define Relay 3
#define freqOn 300 //как часто можно включать в минутах
unsigned long cards[6]; //uids карт читаются из eeprom
unsigned long newCardUid; //переменная для хранения неизвестной карты
boolean i = false;
short time[6]; //время на которое карта может включить устройство в минутах, читается из eeprom
unsigned long lastTime[6]; //время последнего использования карты
boolean isOn[6]; //активна ли карта в данный момент
boolean cardPresent; //показывает есть ли хоть одна карта в eeprom
boolean masterPresent = false; //показывает присутствие мастера
boolean newCard = false; //показывает присутствие новой карты
String message;

/* Create an instance of the library (uncomment one of the lines below) */
//HCuOLED HCuOLED(SSD1307, SS_DI, DC_DI, RST_DI); // For SSD1307 displays (HCMODU0050 & HCMODU0052)
HCuOLED HCuOLED(SH1106, CS_DI, DC_DI, RST_DI); // For SH1106 displays (HCMODU0058 & HCMODU0059)

MFRC522 mfrc522(SS_PIN, RST_PIN);	// Create MFRC522 instance

void setup() {        
  Serial.begin(9600);		// Initialize serial communications with the PC
  //while (!Serial);		// Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, HIGH);
  SPI.begin();			// Init SPI bus
  mfrc522.PCD_Init();		// Init MFRC522
  ShowReaderDetails();	// Show details of PCD - MFRC522 Card Reader details
  //Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
  HCuOLED.Reset();
  //HCuOLED.SetFont(MedProp_11pt);
  //HCuOLED.Cursor(40,0);
  //HCuOLED.Print("Uid:");
  //eraseCards();
  cardPresent = readCards();
}

void loop() {
    if((millis()/10000)%2 ^ i) { //check each 10 seconds
      i = !i;
      if(!masterPresent) {
        if(millis() > (someCardsIsOn()-1000)) {
          offRelay(Relay);
          message = "Time over";
        } else {
          message = "Remain:" + String((someCardsIsOn() - millis())/60000+1);
          Serial.println(message);
        }
        drawCardTime(message);
        HCuOLED.Refresh();
      }
    }
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent()) {
		return;
	}

	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial()) {
		return;
	}

        String s = dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
        mfrc522.PICC_HaltA();
        Serial.println(s);
}

void ShowReaderDetails() {
	// Get the MFRC522 software version
	byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
	Serial.print(F("MFRC522 Software Version: 0x"));
	Serial.print(v, HEX);
	if (v == 0x91)
		Serial.print(F(" = v1.0"));
	else if (v == 0x92)
		Serial.print(F(" = v2.0"));
	else
		Serial.print(F(" (unknown)"));
	Serial.println("");
	// When 0x00 or 0xFF is returned, communication probably failed
	if ((v == 0x00) || (v == 0xFF)) {
		Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
	}
}

String dump_byte_array(byte *buffer, byte bufferSize) {
    String s;
    unsigned long uiddec = 0;
    unsigned long temp;
    char uid[8];
    for (byte m = (bufferSize > 4 ? (bufferSize - 4) : 0); m < bufferSize; m++) { //берем только последние 4 байта и переводим в десятичную систему
        unsigned long p = 1;
        for(int k = 0; k < bufferSize-m-1; k++) {
          p = p*256;
        }
        uiddec += p*buffer[m];
        s = s + (buffer[m] < 0x10 ? "0" : "");
        s = s + String(buffer[m], HEX);
    }
    s.toCharArray(uid, 8);
    drawUid(uid);
    drawLong(uiddec);
    message = "unknow";
    short currentCard = -1;
    for(int k = 0; k <6; k++) { //сравнимаем полученный uid с тем что хранится в массиве карт
      if((time[k] >=0) && (cards[k] == uiddec)) {
        currentCard = k;
      }
    }
    if(currentCard > 0) { //карта найдена, но она не мастер
      message = onRelay(Relay, currentCard);
    } else {
      if(currentCard == 0) { //приложили мастер, если новая карта приложена ранее, то записать ее в EEPROM, если нет, то сделать выход мастеру
        if(!masterPresent) {
          newCard = false;
          masterPresent = true;
          message = "master in";
          onRelay(Relay, currentCard);
        } else {
          if(newCard) {
            for(int k = 1; k < 6; k++) {
              if(time[k] < 0) {
                writeNewCard(newCardUid,k);
                //Serial.println("new card write to " + String(k));
                newCard = false;
                message = "card added";
                break;
              }
            }
          } else {
            masterPresent=false;
            offRelay(Relay);
            message = "master out";
          }
        }
      } else { //если время меньше 0, то неизвестная карта, если мастер есть, то добавить, если нет то сообщить, что карта неизвестна
        if(masterPresent) {
          newCard = true;
          newCardUid = uiddec;
          message = "confirm?";
        } else {message = "unknow";}
      }
    }
    if(!cardPresent) { //если карт нет, то записать карту как мастер
      short master = 0;
      EEPROM_write(0, uiddec);
      EEPROM_write(4, master);
      message = "NEW MASTER";
      cardPresent = true;
      readCards();
    }
    if(uiddec == 696374757) {
      eraseCards();
      cardPresent = readCards();
      message = "ERASED";
    }
    drawCardTime(message); 
    return s;
}

void drawUid(char *s) {
        HCuOLED.Erase(0,16,120,32);
        HCuOLED.SetFont(MedProp_11pt);
        HCuOLED.Cursor(0,16);
        HCuOLED.Print(s);
        HCuOLED.Refresh();
}

void drawLong(long uid) {
        HCuOLED.Erase(0,33,120,48);
        HCuOLED.SetFont(MedProp_11pt);
        HCuOLED.Cursor(0,33);
        HCuOLED.Print(uid);
        HCuOLED.Refresh();
}

void drawCardTime(String s) {
  char mess[12];
  s.toCharArray(mess, 12);
  HCuOLED.Erase(0,49,120,80);
  HCuOLED.SetFont(MedProp_11pt);
  HCuOLED.Cursor(0,49);
  HCuOLED.Print(mess);
  HCuOLED.Refresh();
}

void eraseCards() {
  short master = -1;
  for(int t = 0; t < 40; t++) {
  EEPROM_write(t*2, master);}
  readCards();
  //Serial.println("Cards erased");
}

boolean readCards() {
  cardPresent = false;
  for(int k = 0; k <6; k++) {
    EEPROM_read(k*6+4, time[k]);
    if(time[k] >= 0) {
      cardPresent = true;
      EEPROM_read(k*6, cards[k]);
      //Serial.print(cards[k]);
      //Serial.print(" - ");
      //Serial.println(time[k]);
      }
  }
  return cardPresent;
}

void writeNewCard(unsigned long uid, int k) {
  short time = 30;
  EEPROM_write(k*6, uid);
  EEPROM_write(k*6+4, time);
  readCards();
}

String onRelay(int relayPin, short card) {
  String messa;
  if(time[card] == 0) { //мастер пришел
    offAllCards(); //выключить все карты
    messa = "master ON";
    digitalWrite(relayPin, LOW); //включить реле
  } else {
    if(!isOn[card]) { //если карта не включена
      unsigned long lastOn = (lastTime[card] == NULL ? 0 : lastTime[card]); //последнее включение карты 
      if((millis()-lastOn)/60000 > (freqOn - 1)) { //если последнее включение было раньше, чем разрешенная частота использования
        messa = "time:" + String(time[card]);
        lastTime[card] = someCardsIsOn() + time[card]*60000; //установить время последнего использования в максимальное время из действующих карт + разрешенное время
        isOn[card] = true; //пометить что это одна из действующих карт
        digitalWrite(relayPin, LOW); //включить реле
      } else { //сообщить когда снова можно будет пользоваться
        short waitminutes = freqOn - (millis()-lastOn)/60000; //сколько осталось минут до возможности включить
        messa = "Wait:" + String(waitminutes/60) + "h" + String(waitminutes%60)+ "m";
        //messa = String(waitminutes);
      }
    } else {
      messa = "Allready ON";
    }
  }
  return messa;
}

void offRelay(int relayPin) {
  offAllCards();
  digitalWrite(relayPin, HIGH);
}

void offAllCards() {
  for(int k = 0; k < 10; k++) {
    isOn[k] = false;
  }
}

unsigned long someCardsIsOn() {
  unsigned long maxtime = millis();
  for(int k = 0; k <6; k++) {
    if(isOn[k]&&(lastTime[k] > maxtime)) {
      maxtime = lastTime[k];
    }
  }
  return maxtime;
}


Схема подключения:

image


Ссылка на скетч

Демонстрация работы:



Что хотелось бы изменить/добавить:

1. Сделать возможность на изменение времени использования устройства для карты и ее удаление (прикладывая мастер несколько раз изменять время: 30, 45, 60, 90, 120, -1).
2. Добавить на схему кнопку с помощью которой можно было бы сбрасывать устройство.

Комментарии (22)


  1. MAXXL
    05.10.2015 15:00

    Так а как контролируется что ребенок не воткнет мимо этого девайса в розетку? Ну или купит свой кабель и воткнет в телик?


    1. tmv002
      05.10.2015 15:14

      Это пост не о том как зафиксировать кабель в телевизоре и розетке. Но если вам интересно, то реле с розеткой и вилкой я убрал в пластиковую коробку, которую нельзя вскрыть без повреждения, в ТВ зафиксировал кабель с помощью мест под настенные крепление.


  1. shornikov
    05.10.2015 15:01
    +1

    Удлинитель поможет ребенку.
    Хотя, им можно и по заднице…


  1. alexpp
    05.10.2015 15:03
    +4

    — Сын, а как ты умудрился столько времени смотреть телек, там же защита?
    — А у меня проездной!


  1. istui
    05.10.2015 16:01

    Есть фото устройства в сборе?


    1. tmv002
      05.10.2015 21:58
      +1

      Чуть позже сфоткаю и добавлю


  1. Rumlin
    05.10.2015 16:03
    +1

    off А что там по ТВ такого интересного? /off
    Может лучше вообще от ТВ в доме избавиться.


    1. nochkin
      05.10.2015 18:36
      +2

      Правильно. А на сэкономленные деньги купить микроконтроллеры и обвязку, что бы начать с сыном изучать программирование. Это затягивает больше телевизора.


      1. Rumlin
        05.10.2015 21:49

        Мечты. У меня ТВ в доме нет, но деньги всё равно куда-то испаряются. :)


        1. tmv002
          05.10.2015 21:57
          +1

          у меня несколько лет антенна к ТВ не подключена была, смотрим только фильмы скачанные в интернете, но год назад перешел на онлайм интернет +ТВ + телефон, ну и подключил на свою голову.


    1. r00tGER
      06.10.2015 08:41

      В ТВ много чего интересного, всё зависти от канала. Не везде «новости» весь день.
      Согласен, что даже Дискавери сильно опопсел и много повторов, но годные передачи есть.
      И, главное можно с пользой увлечь школьника.

      -офф
      Новости иногда тоже полезно смотреть. Надо же знать, чем живет Страна :)


  1. VBKesha
    05.10.2015 17:03
    +3

    Мне интересно пошла ли успеваемость вверх?
    По себе вспоминаю что я всегда мог придумать чем заняться вместо уроков. Мне вот интересно хоть на кого то действуют данные методы?


    1. tmv002
      05.10.2015 17:57
      +3

      Не особо. Просто теперь он стал больше гулять и читать. Всё лучше чем телек целый день смотреть.


  1. IronHead
    05.10.2015 17:18
    +1

    Совсем вы не знаете психологию детей. Вместо того, чтобы ограничивать — нужно заинтересовать и стимулировать.
    Для примера: Хочешь новую игру на комп? Две недели подряд ни одной плохой оценки и на следующих выходных играешь сколько хочешь.
    Вот мотивация. Причем нельзя ставить слишком большие сроки (неделя — максимум две, иначе потеряет интерес) и нельзя безапелляционно рубить с плеча, если всю неделю учился хорошо, а тут в пятницу плохая оценка нарисовалась — сделайте поблажку.
    А так он телевизор не посмотрит, но и уроки делать не будет — найдет чем заняться.


    1. tmv002
      05.10.2015 18:03

      Наверное сами вы не очень хороший психолог, если делаете столь поспешные выводы о не знакомому человеке. К ребёнку применяются различные методы поощрения и наказания. Есть вполне доступный для него kpi, который включает в себя несколько параметров включая оценки в школе, порядок в комнате, выполнение спортивных упражнений и т.д. Ведь невозможно кого-то мотивировать гуталином, если у него дядя на гуталиновой фабрике работает, поэтому сначала надо ограничить доступ к гуталину.


      1. Konachan700
        05.10.2015 21:06
        +1

        Нужна мотивация, а не система наказаний. Описанное в статье — именно наказание. На взгляд ребенка, конечно. У меня в семье тоже такое практиковали, денди час в день, компьютер — полтора, ну и что толку? Учеба не улучшилась ни на грамм, а свободное время убивалось на всякую лажу, например, читал учебник ихтиологии или писал бредятину театральному кружку. Теперь ну очень широкий кругозор, но ни мотивации, ни стремления к успеху, ничего. Одна философия на диване.
        А вот кое у кого в классе отец отложил пару крупных премий и сказал сыну: «будут годовые пятерки все — на два месяца поедешь в летний лагерь в США, не будет — поедешь с нами к бабушке в Тулу, по огороду помогать.» Все. Малой из кожи вон лез, чтобы обеспечить заветные оценки. И поехал в лагерь. В следующем году ему отец еще одну плюшку обещал, и опять парень ее заработал, достиг. И самое главное — его родителей не интересовало, сколько он играет в сегу, сколько и до скольких гоняет во дворе мяч, ну, пока разумной меры не превышал. А потом этот ритм жизни и мотивация к достижению успеха стали привычкой. Сейчас товарищ имеет неплохой бизнес и шило в одном месте в хорошем смысле.
        KPI для ребенка, особенно сложные, это сразу минус к любой мотивации. Если ребенок не классический интроверт-тихоня, конечно. Малому нужна яркая обособленная цель, желательно с хорошим вознаграждением. Вот тогда будет мотивация. Мотивация к достижению цели, вместе с умением легко учиться новому — самое ценное в наше время. Знания теперь есть у гугла и зубрить кучу информационного мусора попросту незачем.


        1. tmv002
          05.10.2015 21:35

          По вашему пусть все остается как есть? Пусть дальше смотрит сколько влезет?
          Его KPI нацелен только на поощрение. Надеюсь вы не будете спорить, что каждый ребенок индивидуальность, поэтому не надо рассуждать, о том кого вы не знаете.


  1. avs24rus
    06.10.2015 05:54
    +1

    Жаль что в 90е со всем этим (я имею ввиду микроконтроллеры) было значительно сложнее, а то я бы тоже сделал нечто подобное.
    Но их (детей) больше затягивал не телевизор, а компьютер, а уж тут то с контролем все гораздо проще.


  1. Zzzuhell
    06.10.2015 14:35

    Распиновочку Mifare RC522 не подскажете? В том смысле, какие у вас контакты задействованы.
    Почему спрашиваю — у меня лежит аналогичный (по описанию) RFID модуль, который я никак не могу заставить работать с ардуиной. Хочу понять — подойдет ли ваша библиотека или не стоит заводиться…


    1. spc
      06.10.2015 14:42

      В примерах библиотеки все есть:

      * Typical pin layout used:
       * -----------------------------------------------------------------------------------------
       *             MFRC522      Arduino       Arduino   Arduino    Arduino          Arduino
       *             Reader/PCD   Uno           Mega      Nano v3    Leonardo/Micro   Pro Micro
       * Signal      Pin          Pin           Pin       Pin        Pin              Pin
       * -----------------------------------------------------------------------------------------
       * RST/Reset   RST          9             5         D9         RESET/ICSP-5     RST
       * SPI SS      SDA(SS)      10            53        D10        10               10
       * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
       * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
       * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
      



      1. Zzzuhell
        06.10.2015 14:45

        Увидел, спасибо.
        Не мой вариант, к сожалению.
        У меня Rx/Tx. Да и сам ридер сильно другой


  1. mugisbrows
    16.10.2015 20:23

    Вся суть компьютерного инженера