Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Arduino Mega: съёмка фото и автоматическая загрузка в Google Drive

Компоненты и материалы

Arduino Mega 2560 1
PHPoC WiFi Shield 2 для Arduino 1
Seeed Grove - Serial Camera Kit 1
Seeed Grove Base Shield 1
Кнопка 1

О проекте

Если вы новичок, начните с основ Arduino.

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

Как это работает

  1. Вход в Google-аккаунт через OAuth 2.0 для IoT-устройств для получения access_token. Процесс описан в проекте на Hackster.
  2. При нажатии кнопки Arduino получает фото с камеры и загружает в Google Drive через Google Drive API, используя access_token. API описан в документации Google.

Пошаговая инструкция

Другие аппаратные платформы

Аналогичный проект для другой платформы доступен здесь.

Лучший стартовый набор Arduino для новичка

Рекомендации по выбору набора: The Best Arduino Kit for Beginners.

Справочник функций

Код

Основной скетч Arduino (ArduinoGoogleDrive)

#include <Phpoc.h>
#include <Arduino_JSON.h>
#include "grove_camera.h"

String GOOGLE_CLIENT_ID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";
String GOOGLE_CLIENT_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxx";

PhpocServer websocket_server(80);

String http_resp_hearder(PhpocClient &client) { /* ... */ }
String http_resp_body(PhpocClient &client) { /* ... */ }

String access_token = "";
String refresh_token = "";
unsigned long access_token_expire_at = 0;

void websocket_send(String msg) { /* ... */ }

void googleDeviceOAuthLogin() { /* OAuth 2.0 Device Flow для Google */ }

void cameraToGoogleDrive() {
  if (access_token == "") { Serial.println("access_token is invalid"); return; }
  long picture_len = cameraGetPicture();
  if (picture_len) {
    PhpocDateTime datetime;
    PhpocClient client;
    String file_name, metadata, jpeg_boundary, end_boundary;
    datetime.date("YmdHis");
    file_name = datetime.date();
    metadata = "--foo_bar_baz\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n";
    metadata += "{\"title\": \"ARDUINO_" + file_name + "\"}\r\n\r\n";
    jpeg_boundary = "--foo_bar_baz\r\nContent-Type: image/jpeg\r\n\r\n";
    end_boundary = "\r\n--foo_bar_baz--";
    unsigned long body_len = metadata.length() + jpeg_boundary.length() + picture_len + end_boundary.length();
    int total = 0;
    if (client.connectSSL("www.googleapis.com", 443)) {
      Serial.println("Connected to server");
      client.println("POST /upload/drive/v2/files?uploadType=multipart HTTP/1.1");
      client.println("Host: www.googleapis.com");
      client.println("Connection: close");
      client.println("Accept: */*");
      client.println("Content-Type: multipart/related; boundary=foo_bar_baz");
      client.print("Content-Length: "); client.println(body_len);
      client.print("Authorization: Bearer "); client.println(access_token);
      client.println();
      client.print(metadata);
      client.print(jpeg_boundary);
      int packet_num = cameraPacketNum();
      char packet[PIC_PKT_LEN] = {0};
      for (int i = 0; i < packet_num; i++) {
        long packet_len = cameraGetPacket(i, packet);
        client.write((const uint8_t *)&packet[4], packet_len - 6);
        total += packet_len - 6;
      }
      cameraGetPacket(packet_num, packet);
      client.print(end_boundary);
      String response_hearder = http_resp_hearder(client);
      String response_body = http_resp_body(client);
      Serial.println(response_body);
    }
  } else { Serial.print("picture_len:"); Serial.println(picture_len); }
}

int buttonState, lastButtonState = LOW;
unsigned long lastDebounceTime = 0, debounceDelay = 50;

bool isButtonPressed(int pin) {
  int reading = digitalRead(pin);
  if (reading != lastButtonState) lastDebounceTime = millis();
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) return true;
    }
  }
  lastButtonState = reading;
  return false;
}

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
  websocket_server.beginWebSocket("login");
  Serial.print("WebSocket server address: "); Serial.println(Phpoc.localIP());
  pinMode(2, INPUT);
  cameraInit(CT_JPEG, PR_160x120, JR_640x480);
}

void loop() {
  PhpocClient client = websocket_server.available();
  if (client) {
    String ws_str = client.readLine();
    if (ws_str == "google\r\n") googleDeviceOAuthLogin();
  }
  if (isButtonPressed(2)) {
    if (access_token != "" && access_token_expire_at > millis()) cameraToGoogleDrive();
    else Serial.println("access_token is invalid, please login again");
  }
}

login.php (загружается на PHPoC Shield)

<html><head><title>PHPoC / <?echo system("uname -i")?></title>
<meta content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=0.5, width=device-width, user-scalable=yes" name="viewport">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto" type="text/css">
<style> /* CSS для UI входа */ </style>
<script> /* WebSocket-клиент для взаимодействия с Arduino */ </script>
</head><body>
<div class="center">
<div class="hearder"><div style="font-size: 150%">
<span style="color:#4285F4">G</span><span style="color:#EA4335">o</span><span style="color:#FBBC05">o</span>
<span style="color:#4285F4">g</span><span style="color:#34A853">l</span><span style="color:#EA4335">e</span>
</div>Login for Arduino</div><br><br>
<div class="wc_text" id="wc_text"></div><br><br>
<div class="loader" id="loader"><div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div></div>
</div></body></html>

grove_camera.h (библиотека для Grove Camera)

#define PIC_PKT_LEN 512
#define CAM_ADDR 0
// Константы для настройки камеры (цвет, разрешение превью, JPEG)
const byte camera_address = (CAM_ADDR << 5);
unsigned int camera_packet_num, camera_last_packet_len;

void cameraClearRxBuf() { while (Serial.available()) Serial.read(); }
void cameraSendCmd(char cmd[], int cmd_len) { for (char i=0;i

Схемы

Arduino Mega: съёмка фото и автоматическая загрузка в Google Drive

Производственный процесс

  1. Сборка Bluetooth-робота-шпиона на Arduino с управлением с телефона
  2. FlickMote: жестовое IR-пульт для умного дома на Arduino 101 и ультразвуковом датчике
  3. DIY Arduino TV-B-Gone: универсальный пульт для выключения любого телевизора
  4. Создание пользовательских LED-часов с будильником — видно с 12 метров
  5. Find Me: Умный поисковик вещей на Arduino и Bluetooth
  6. Оптимизированные решения питания для проектов на Arduino
  7. Крестики-нолики на Arduino с матрицей MAX7219 и картонным корпусом
  8. Пошаговое руководство: сборка умного четырёхногого робота на Arduino
  9. Голосовое управление бытовыми приборами: Bluetooth-управление через Google Assistant
  10. Инвестиции Google $450M в ADT ускоряют внедрение IoT-безопасности