Не могу никак запустить заведомо рабочую версию скетча-поможите !

SEEK
Offline
Зарегистрирован: 01.02.2013

 

Приветствую всех! Возникла следующая проблема-  есть заведомо рабочий код(сегодня для верности даже говорил с его автором, -так что тут все ок), - который написан под arduino ide 18. У автора нет достаточного времени чтобы вместе со мной разбираться в тонкостях-поэтому спрашиваю здесь...

СУТЬ ПРОБЛЕМЫ: не могу залить скетч в ардуино (всякие тестовые библиотечные, самописные скетчи-заливаются на ура и все работает-проблема не в ардуине).

Подумал что наверное это из за того, что скетч написан под старую IDE и глючит под моей...Ок...пошел на arduino.cc и скачал 17,18,19 версии IDE. Ни под одной не завелось!

Был бы благодарен, если бы вы подредактировали скетч и сказали под какой версией IDE он у вас все таки прошел тестовую компиляцию! Я уже сам- все что можно перепробовал-ну никак...

Спасибо заранее огромное!

А вот сам скетч:  http://rusfolder.com/36042451

SEEK
Offline
Зарегистрирован: 01.02.2013

Кстати забыл сказать -использую arduino ethernet (плата, где объединены arduino uno и ethernet shield)

toc
Offline
Зарегистрирован: 09.02.2013

Какая у вас возникает ошибка?

SEEK
Offline
Зарегистрирован: 01.02.2013

Если в последних версиях IDE  запускаю- то пишет надо переименовать client -в ethernetclient. Переименовываю-пишет что нет соответствующей функции.

А когда запускаю в 18 IDE- то пишет: "Error: PString.h -no such file or directory"

 

А вот собственно сам скетч(это создание управляемой веб камеры по статье вот отсюда: http://habrahabr.ru/post/108058/ ):


#include <Ethernet.h>
#include <Servo.h>
#include <PString.h>
#include <WString.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };
byte ip[] = { 192, 168, 1, 100 };
byte server[] = { 82, 138, 2, 107 }; // G0l.ru

int CONNECT_WAIT = 10; // задержка (в милисекундах) между следующей попыткой коннекта с сервером
int SLOW_MOVE_DELAY = 10; // задержка между тактами при медленном дискретном перемещении
int MOVE_DELAY = 10;     // задержка между тактами при пропорциональном перемещении
int max_length = 20; // максимальная длинна буфера для строк
int max_x = 180, 
    max_y = 180,
    min_x = 1, 
    min_y = 1; // искусственно ограничиваем углы вращения, дабы камера не билась башкой о стол
int init_X = 90, init_Y = 90;
int delta_x = 5, delta_y = 5; // шаг изменения позиции

int X = init_X; // текущее положение по оси Х, начальное значение - примерно середина (90)
int Y = init_Y; // текущее положение по оси Y, начальное значение - примерно середина (90)
int old_X = X, old_Y = Y; // для сохраннения предыдущей позиции

Servo myservo, myservo1;  // создаём объект для каждой сервы
Client client(server, 80); // создаём объект для подключения к серверу
boolean Action = false; // семафор, если true - строка получена и укомплектована, можно разбирать
int repeat = 0;
String buffer = String(max_length);
int val1, val2; // промежуточная переменная при преобразовании типов

void setup()
{
  // Задаём первичные настройки
  Ethernet.begin(mac, ip);    // куда будем подключаться по сети
  Serial.begin(9600);         // в консоль будем писать текущее состояние дел
  myservo.attach(7);          // серва Y подключена к 7-му пину
  myservo1.attach(6);         // серва X подключена к 6-му пину
}

void loop()
{
  // Если не приконнектились - ждём 100 милисекунд и снова пробуем приконнектиться
  if (!client.connected()) {
     Serial.println("Client stop");
     client.stop();
     delay(CONNECT_WAIT);
     repeat = 0; // на всякий случай обнуляем флаг повторности подключения (во загнул). 
                 //Эт чтоб в консоль по сто раз не выводилось сообщение о коннекте
     if (client.connect()) {
       Serial.println("Client connect ");
       if (!repeat) {
         Serial.println("ok"); // теперь мы подключены к серверу 
         repeat = 1; // выставляем уже известный флаг
        }

       // отправляем запрос к скрипту на сервере
       client.print("GET /test/serva/get.php HTTP/1.0\r\n");
       client.print("Host: www.g0l.ru\r\n");
       client.println();
       Serial.println("Sending HTTP request");

       Action = false;
     }
  }
  if (client.available()) {
    // при установленнном подключении к серверу
    char c = client.read(); // читаем символ
    if (c == '\n') {      
      // Строка готова, можно разбирать. Правда, сначала заголовок идёт, но нам пофиг, его мы как-то отделять не будем
      if (buffer.length()) Action = true;
      if (Action) {
	Action = false;
        old_X = X;
        old_Y = Y;
        // Собссно, обработка команд
        if (buffer.contains("{1}")) { 
          // Двигаем вверх
          Y += delta_y; 
          if (Y > max_y) Y = max_y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.contains("{2}")) { 
          // Двигаем вниз
          Y -= delta_y; 
          if (Y < min_y) Y = min_y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.contains("{3}")) { 
          // Центрируем по оси Y
          Y = init_Y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.contains("{4}")) { 
          // Двигаем вверх до упора
          Y = max_y;  
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.contains("{5}")) { 
          // Двигаем вниз до упора
          Y = min_y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.contains("{6}")) { 
          // двигаем влево
          X -= delta_x; 
          if (X < min_x) X = min_x;
          ServoSlowMove(1, old_X, X);  
        }

        if (buffer.contains("{7}")) {
          // двигаем вправо
          X += delta_x; 
          if (X > max_x) X = max_x;
          ServoSlowMove(1, old_X, X);  
        }

        if (buffer.contains("{8}")) { 
          // Двигаем влево до упора
          X = min_x;  
          ServoSlowMove(1, old_X, X); 
        }

        if (buffer.contains("{9}")) { 
          // Двигаем вправо до упора
          X = max_x;  
          ServoSlowMove(1, old_X, X); 
        }

        if (buffer.contains("{10}")) { 
          // центрирование по оси X
          X = 90;  
          ServoSlowMove(1, old_X, X); 
        }

        // Теперь самое интересное -         
        // Пропорциональные мгновенные перемещения. Т.е. полученные координаты мышки при движении по управляющей области
        if (buffer.contains("{11}")) {            
            // разбираем строку виде {11}xxxyyy, где {11} - код перемещения, xxx - координата X, yyy - координата Y (Спасибо, Кэп!)
            String value = buffer.substring(4);
            String value1 = value.substring(0,3);
            String value2 = value.substring(3);
            val1 = atoi(value1);
            val2 = atoi(value2);
            val2 = max_y - val2;
            
            if (val1 > max_x) val1 = max_x;
            if (val1 < min_x) val1 = min_x;
            if (val2 > max_y) val2 = max_y;
            if (val2 < min_y) val2 = min_y;
                                    
            ServoMove(val1, val2); 
            X = val1;  
            Y = val2;  
        }
      }
      
      // Конец обработки готовой строки
      buffer = ""; // обнуляем строку
    } else {
      if (c != '\r' && buffer.length() < max_length) buffer.append(c); // добавляем символ в наш буфер
    }
  }
}


void ServoSlowMove(int n, int pos1, int pos2){
  // Функция медленного перемещения сервы n из одного положения pos1 в другое pos2.
  if (pos1==pos2) return;
  if (pos1 < pos2) 
    for (int i = pos1; i <= pos2 ; i++) {
        n?myservo1.write(i):myservo.write(i);
        delay(SLOW_MOVE_DELAY);
    }
   else
    for (int i = pos1; i >= pos2 ; i--) {
        n?myservo1.write(i):myservo.write(i);
        delay(SLOW_MOVE_DELAY);
    }
}

void ServoMove(int x, int y){
  myservo1.write(x); 
  myservo.write(y);
  delay(MOVE_DELAY);
}
vvadim
Offline
Зарегистрирован: 23.05.2012

Проверьте наличие и правильность установки библиотек указанных в коде.

SEEK
Offline
Зарегистрирован: 01.02.2013

Все-помучившись установил таки недостающие библиотеки!

Но новая напасть: при тестовой компиляции ругается на строку 148 и 149 в коде выше - пишет: 

error: cannot convert 'String' to 'const char*' for argument '1' to 'int atoi(const char*)'

error: cannot convert 'String' to 'const char*' for argument '1' to 'int atoi(const char*)'

 

maksim
Offline
Зарегистрирован: 12.02.2012
  val1 = value1.toInt();
  val2 = value2.toInt();

 

SEEK
Offline
Зарегистрирован: 01.02.2013

не вышло-пишет:

error: 'class String' has no member named 'toInt'

P.S. запускаю в ARDUINO IDE 20 - если брать еще более высокие версии- то надо еще более глубоко перерабатывать скетч. 

maksim
Offline
Зарегистрирован: 12.02.2012

Качаете ArduinoIDE 1.0.X и радуетесь, ибо доработок в коде на 5 минут.

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };
byte ip[] = { 192, 168, 1, 100 };
byte server[] = { 82, 138, 2, 107 }; // G0l.ru

int CONNECT_WAIT = 10; // задержка (в милисекундах) между следующей попыткой коннекта с сервером
int SLOW_MOVE_DELAY = 10; // задержка между тактами при медленном дискретном перемещении
int MOVE_DELAY = 10;     // задержка между тактами при пропорциональном перемещении
int max_length = 20; // максимальная длинна буфера для строк
int max_x = 180, 
    max_y = 180,
    min_x = 1, 
    min_y = 1; // искусственно ограничиваем углы вращения, дабы камера не билась башкой о стол
int init_X = 90, init_Y = 90;
int delta_x = 5, delta_y = 5; // шаг изменения позиции

int X = init_X; // текущее положение по оси Х, начальное значение - примерно середина (90)
int Y = init_Y; // текущее положение по оси Y, начальное значение - примерно середина (90)
int old_X = X, old_Y = Y; // для сохраннения предыдущей позиции

Servo myservo, myservo1;  // создаём объект для каждой сервы
EthernetClient client; // создаём объект для подключения к серверу
boolean Action = false; // семафор, если true - строка получена и укомплектована, можно разбирать
int repeat = 0;
String buffer = String(max_length);
int val1, val2; // промежуточная переменная при преобразовании типов

void setup()
{
  // Задаём первичные настройки
  Ethernet.begin(mac, ip);    // куда будем подключаться по сети
  Serial.begin(9600);         // в консоль будем писать текущее состояние дел
  myservo.attach(7);          // серва Y подключена к 7-му пину
  myservo1.attach(6);         // серва X подключена к 6-му пину
}

void loop()
{
  // Если не приконнектились - ждём 100 милисекунд и снова пробуем приконнектиться
  if (!client.connected()) {
     Serial.println("Client stop");
     client.stop();
     delay(CONNECT_WAIT);
     repeat = 0; // на всякий случай обнуляем флаг повторности подключения (во загнул). 
                 //Эт чтоб в консоль по сто раз не выводилось сообщение о коннекте
     if (client.connect(server, 80)) {
       Serial.println("Client connect ");
       if (!repeat) {
         Serial.println("ok"); // теперь мы подключены к серверу 
         repeat = 1; // выставляем уже известный флаг
        }

       // отправляем запрос к скрипту на сервере
       client.print("GET /test/serva/get.php HTTP/1.0\r\n");
       client.print("Host: www.g0l.ru\r\n");
       client.println();
       Serial.println("Sending HTTP request");

       Action = false;
     }
  }
  if (client.available()) {
    // при установленнном подключении к серверу
    char c = client.read(); // читаем символ
    if (c == '\n') {      
      // Строка готова, можно разбирать. Правда, сначала заголовок идёт, но нам пофиг, его мы как-то отделять не будем
      if (buffer.length()) Action = true;
      if (Action) {
	Action = false;
        old_X = X;
        old_Y = Y;
        // Собссно, обработка команд
        if (buffer.indexOf("{1}") >= 0) { 
          // Двигаем вверх
          Y += delta_y; 
          if (Y > max_y) Y = max_y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.indexOf("{2}") >= 0) { 
          // Двигаем вниз
          Y -= delta_y; 
          if (Y < min_y) Y = min_y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.indexOf("{3}") >= 0) { 
          // Центрируем по оси Y
          Y = init_Y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.indexOf("{4}") >= 0) { 
          // Двигаем вверх до упора
          Y = max_y;  
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.indexOf("{5}") >= 0) { 
          // Двигаем вниз до упора
          Y = min_y;
          ServoSlowMove(0, old_Y, Y); 
        }

        if (buffer.indexOf("{6}") >= 0) { 
          // двигаем влево
          X -= delta_x; 
          if (X < min_x) X = min_x;
          ServoSlowMove(1, old_X, X);  
        }

        if (buffer.indexOf("{7}") >= 0) {
          // двигаем вправо
          X += delta_x; 
          if (X > max_x) X = max_x;
          ServoSlowMove(1, old_X, X);  
        }

        if (buffer.indexOf("{8}") >= 0) { 
          // Двигаем влево до упора
          X = min_x;  
          ServoSlowMove(1, old_X, X); 
        }

        if (buffer.indexOf("{9}") >= 0) { 
          // Двигаем вправо до упора
          X = max_x;  
          ServoSlowMove(1, old_X, X); 
        }

        if (buffer.indexOf("{10}") >= 0) { 
          // центрирование по оси X
          X = 90;  
          ServoSlowMove(1, old_X, X); 
        }

        // Теперь самое интересное -         
        // Пропорциональные мгновенные перемещения. Т.е. полученные координаты мышки при движении по управляющей области
        if (buffer.indexOf("{11}") >= 0) {            
            // разбираем строку виде {11}xxxyyy, где {11} - код перемещения, xxx - координата X, yyy - координата Y (Спасибо, Кэп!)
            String value = buffer.substring(4);
            String value1 = value.substring(0,3);
            String value2 = value.substring(3);
            val1 = value1.toInt();
            val2 = value2.toInt();
            val2 = max_y - val2;
            
            if (val1 > max_x) val1 = max_x;
            if (val1 < min_x) val1 = min_x;
            if (val2 > max_y) val2 = max_y;
            if (val2 < min_y) val2 = min_y;
                                    
            ServoMove(val1, val2); 
            X = val1;  
            Y = val2;  
        }
      }
      
      // Конец обработки готовой строки
      buffer = ""; // обнуляем строку
    } else {
      if (c != '\r' && buffer.length() < max_length) buffer.concat(c); // добавляем символ в наш буфер
    }
  }
}


void ServoSlowMove(int n, int pos1, int pos2){
  // Функция медленного перемещения сервы n из одного положения pos1 в другое pos2.
  if (pos1==pos2) return;
  if (pos1 < pos2) 
    for (int i = pos1; i <= pos2 ; i++) {
        n?myservo1.write(i):myservo.write(i);
        delay(SLOW_MOVE_DELAY);
    }
   else
    for (int i = pos1; i >= pos2 ; i--) {
        n?myservo1.write(i):myservo.write(i);
        delay(SLOW_MOVE_DELAY);
    }
}

void ServoMove(int x, int y){
  myservo1.write(x); 
  myservo.write(y);
  delay(MOVE_DELAY);
}

 

SEEK
Offline
Зарегистрирован: 01.02.2013

Ну вы просто спасли меня! спасибо very big  :)  -все получилось! . У меня там еще будет вопрос по расширению мелкому-его чуток попозжа надо будет...если еще раз обращусь- не серчайте сильно... ;-). Там суть простецкая- с сайта человек управляет вебкамерой(это сейчас реализовано) и надо сделать чтобы мог нажать левую кнопку мыши. И при нажатии один из пинов переходил в положение HIGH(на время нажатия кнопки мыши-отпустил- полоджение HIGH пропало). Это надо для управления мышью -через силовой ключ - нагрузкой. Например фонариком. Нажал кнопку мыши-загорелся фонарик. отпустил-погас.

Но там уже и в веб форме и в базе данных надо вносить изменения как я понимаю. Плюс-в скетче(в разбор строки поступающей надо видимо включить разбор события нажатия мыши)...

SEEK
Offline
Зарегистрирован: 01.02.2013

Но о чем я говорил выше- это пока не актуально. Для начала тестирования мне надо бы еще одну вещь выяснить - 

Если посмотреть на строки 006,007 - там надо указывать mac адрес ардуины, ip адрес ее сетевой карты: 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };
byte ip[] = { 192, 168, 1, 100 };

Не подскажете где можно взять эти данные? Спасибо!

maksim
Offline
Зарегистрирован: 12.02.2012

Что значит где взять? Это они и есть МАК и ИП дуины - вы их назначаете.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

SEEK пишет:

Если посмотреть на строки 006,007 - там надо указывать mac адрес ардуины, ip адрес ее сетевой карты: 

Не подскажете где можно взять эти данные?

Вообще говоря, MAC адрес идентифицирует карту, как источник эзернет-фреймов внутри одного сегмента сети, IP адрес - делает то же самое, но в более широком пространстве. :) В железных сетевых картах MAC адрес формируется из имени производителя карты и уникального идентификатора и уже прошит в карте, в модулях ардуино - надо назначать самостоятельно... Поскольку, повторюсь, MAC не выходит за пределы сегмента сети - он должен быть уникален в этом сегменте, вот и все... Понятно, что 0xFF ставить не надо.

IP - адрес - назначаете исходя из параметров своей сети - там, на мой взгляд, сложностей быть не должно.

SEEK
Offline
Зарегистрирован: 01.02.2013

спасибо за ответ, Андрей! Я просто пытаюсь для себя разобраться-так как сегодня планирую все тестить уже в собранном варианте... Поэтому хотелось бы понять -какой mac адрес и ip ставить. Выше был вопрос -"Что значит где взять?"- когда они вроде как в моем коде наверху уже прописаны...Просто повторюсь-я этот код взял у одного человека, автора. И не я прописывал. Я же- просто хотел разобраться- КОНКРЕТНО ДЛЯ МОЕГО СЛУЧАЯ -ip ардуины и mac- оставить как в этом коде или по каким то правилам(где их псмотреть можно?) -назначить самому....

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

SEEK пишет:

просто хотел разобраться- КОНКРЕТНО ДЛЯ МОЕГО СЛУЧАЯ -ip ардуины и mac- оставить как в этом коде или по каким то правилам(где их псмотреть можно?) -назначить самому....

MAC, можно не менять - скорее всего у Вас нет устройств с таким же адресом, а вот IP нужно назначать исходя из адреса/маски именно Вашей сети. Именно пара адрес+маска разделяет адреса в tcpip на "свои" и "чужие". Т.е., если у Вас в сети адреса вида 192.168.21.XXX с маской 255.255.255.0, то назначать (менять) надо именно эти последние XXX, иначе остальные устройства не смогут работать с таким адресом, направляя ответные пакеты для него - в "шлюз по-умолчанию".