Управление Arduino по Bluetooth с мобильного телефона

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY
Ответить
serg
Сообщения: 17
Зарегистрирован: 27 мар 2013, 16:18

Управление Arduino по Bluetooth с мобильного телефона

Сообщение serg »

Доброго времени суток!
Решил перенести управление бульдозером Fishertechnik с компьютера на мобильный телефон Nokia 5130 по Bluetooth.
http://sourceforge.net/p/robotxcontrol/ ... ntrol/src/
- по ссылке любезно предоставленной Григорием находится его проект - именно то что мне и нужно.
К сожалению, мне не удалось запустить jar файл на телефоне Nokia 5130 (series 40 5 edition FeaturePack1). Почему то даже эмулятор Nokia в Eclipse выдает ошибку при запуске этого проекта."Invalid Application. Delete?"
Я нашел еще один проект по управлению Arduino по Bluetooth на сайте Nokia, но как работает Arduino понять не смог.
http://www.developer.nokia.com/Communit ... _Bluetooth

Подскажите, пожалуйста как Arduino "понимает" какой следует зажечь светодиод?
Проверял в эмуляторе- запускается. устанавливал на телефон - запускается. кстати, запускается и на sonyericsson elm. код для Arduino

Код: Выделить всё

#include <SoftwareSerial.h>
 
const int TX_BT = 10;
const int RX_BT = 11;
 
SoftwareSerial btSerial(TX_BT, RX_BT);
 
//Frequency to send periodic messages to  Phone, in milliseconds.
//Core code.
const unsigned long periodicMessageFrequency = 5000;
unsigned long time = 0;
 
//Process the incoming command from  Phone.
//It should be changed according to what you want to do.
void processCommand(char* command) {
}
 
//Send a message back to the  Phone.
//Is can't be changed.
void sendMessage(char* message) {
  int messageLen = strlen(message);
  if(messageLen < 256) {  
    btSerial.write(messageLen);
    btSerial.print(message);
  }
}
 
//Send a set of periodic messages to the  Phone.
//It should be changed according to what you want to do.
//This message could be a sensor data, like a thermometer data.
void sendPeriodicMessages() {
}
 
//Setup Arduino function
void setup() {
  Serial.begin(9600);
  Serial.println("USB Connected");
  btSerial.begin(9600);
}
 
//Loop Arduino function
//It can't be changed
void loop() {
  if(btSerial.available()) {
      int commandSize = (int)btSerial.read();
      char command[commandSize];
      int commandPos = 0;
      while(commandPos < commandSize) {
        if(btSerial.available()) {
          command[commandPos] = (char)btSerial.read();
          commandPos++;
        }
      }
      command[commandPos] = 0;
      processCommand(command);
  }
  unsigned long currentTime = millis();
  if((currentTime - time) > periodicMessageFrequency) {
    sendPeriodicMessages();
    time = currentTime;
  }
}
J2ME коды не копирую. вот ссылка сайта Nokia на архив.
http://www.developer.nokia.com/Communit ... 0426223619
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение Mr.Kubikus »

Привет!

Код для Ардуино, который вы привели, похож на заготовку без конкретного наполнения. В частности, функция, которая отвечает за разбор пакета данных, полученного через Bluetooth, не содержит кода - это пустая заглушка:
//Process the incoming command from Phone.
//It should be changed according to what you want to do.
void processCommand(char* command) {
}
Вам предстоит самостоятельно реализовать алгоритм, который разбирает пакет, полученный от телефона.


Также из кода видно , что приемопередатчик Bluetooth должен подключатся к портам 10 и 11 Arduino:

Код: Выделить всё

const int TX_BT = 10;
const int RX_BT = 11;
Для последовательного приема данных от модуля Bluetooth используется библиотека SoftwareSerial.

Мидлет еще не смотрел.
С уважением, Григорий
GitHub FB ВК
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение Mr.Kubikus »

Мое приложение может не запускаться на вашем Nokia 5130 потому что я разрабатывал его для ОС Symbian v9.1 и платформы S60 3rd Edition (initial release).
С уважением, Григорий
GitHub FB ВК
serg
Сообщения: 17
Зарегистрирован: 27 мар 2013, 16:18

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение serg »

Я знал что Nokia 5500 sport работает под Symbian. Непонятно почему в Eclipse запускается только один RoboTXControl.java. А при запуске всего проекта выдается ошибка.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение Mr.Kubikus »

А на каком эмуляторе вы проверяете приложение RoboTXControl ?
С уважением, Григорий
GitHub FB ВК
serg
Сообщения: 17
Зарегистрирован: 27 мар 2013, 16:18

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение serg »

Сначала поставил Eclipse Indigo и Nokia SDK для своего телефона (да и из любопытства скачал для всех телефонов S40). Потом скачал с сайта Nokia новый SDK с встроенным Indigo. Ошибка одна и та же. Я не ожидал что Java ME для Nokia Symbian настолько отлтичается от Java Me для Nokia S40. Какая библиотека в файле ControlCanvas.java так изменилась за прошедшие годы?
serg
Сообщения: 17
Зарегистрирован: 27 мар 2013, 16:18

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение serg »

Нашел очередную статью об управлении через bluetooth.
http://ricardo-dias.com/2010/04/07/bluetooth-servos/
Надо было установить processing и mobile processing.
http://www.processing.org/download/
К сожалению все проекты давно уже не обновляются
http://mobile.processing.org/download/index.php
это - библиотека bluetoothDesktop- Bluetooth Library for Processing
http://www.extrapixel.ch/processing/bluetoothDesktop/
Очень удобен mobile processing - может делать и мидлеты и апплеты!
Все поставилось в телефон - запустилось. На компьютере - работает и не находит socket BT.
Жаль, снова тупик...
serg
Сообщения: 17
Зарегистрирован: 27 мар 2013, 16:18

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение serg »

Выкладываю код для мобильного телефона. Проверено на SonyEricsson j108i

Код: Выделить всё

import java.util.*;
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.bluetooth.*;

public class blue_tank extends MIDlet implements CommandListener{

	public Display display;
	public Form discoveryForm;
	public Form readyToConnectForm;
	public ImageItem mainImageItem;
	public Image mainImage;
	public Image bt_logo;
	public TextField addressTextField;
	public TextField subjectTextField;
	public TextField messageTextField;
	public Command selectCommand;
	public Command exitCommand;
	public Command connectCommand;
	public List devicesList;
	public Thread btUtility;
	public String btConnectionURL;
	public boolean sendData = false;
        public byte[] outSerial = {0};
        private KeyCodeCanvas canvas;
        public String serialView_out="0";
        public String buttonID="_";
    
	public blue_tank() {
		display=Display.getDisplay(this);
		discoveryForm = new Form("BT Remote");

		try{
		   mainImage = Image.createImage("/arduino.png");
                   bt_logo = Image.createImage("/btlogo.png");
		} catch (java.io.IOException e){
		}
		mainImageItem = new ImageItem("Arduino Bluetooth", mainImage, Item.LAYOUT_CENTER, "");
		discoveryForm.append(mainImageItem);

		btUtility = new BTUtility();

		/// discoveryForm commands initialization

		exitCommand = new Command("Exit", Command.EXIT, 1);
		discoveryForm.addCommand(exitCommand);
		discoveryForm.setCommandListener(this);

		/// devicesList initialization

        devicesList = new List("Select Bluetooth-enabled Device", Choice.IMPLICIT, new String[0], new Image[0]);
	selectCommand = new Command("Select", Command.ITEM, 1);
	devicesList.addCommand(selectCommand);
        devicesList.addCommand(exitCommand);
        devicesList.setCommandListener(this);
        devicesList.setSelectedFlags(new boolean[0]);

		/// readyToConnectForm initialization

		readyToConnectForm = new Form("Ready to Connect");
		readyToConnectForm.append("The selected Bluetooth device is ready to connect.");
		connectCommand = new Command("Connect", Command.ITEM, 1);
		readyToConnectForm.addCommand(connectCommand);
        readyToConnectForm.addCommand(exitCommand);
		readyToConnectForm.setCommandListener(this);

        /// Initailize Canvas
        canvas = new KeyCodeCanvas();
        canvas.addCommand(exitCommand);
        canvas.setCommandListener(this);

    	}

	public void commandAction(Command command, Displayable d) {
		if(command == selectCommand) {
			btUtility.start();
		}
		if(command == exitCommand ) {
			sendData = false;
			destroyApp(true);
		}
		if(command == connectCommand ) {
			Thread commReaderThread = new COMMReader();
			commReaderThread.start();
			display.setCurrent(canvas);
		}

	}


	public void startApp() {
		display.setCurrent(discoveryForm);
	}

	public void pauseApp() {

	}

	public void destroyApp(boolean b) {
		notifyDestroyed();
	}


    /**
     * This is an inner class that is used for finding
     * Bluetooth devices in the vicinity
     *
     */
    class BTUtility extends Thread implements DiscoveryListener{

        Vector remoteDevices = new Vector();
        Vector deviceNames = new Vector();

        DiscoveryAgent discoveryAgent;

        public BTUtility() {

            try {
                LocalDevice localDevice = LocalDevice.getLocalDevice();
                discoveryAgent = localDevice.getDiscoveryAgent();
                discoveryForm.append("Searching for Bluetooth devices...");
                boolean startInquiry = discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
            } catch(BluetoothStateException e) {
                discoveryForm.append("Failed to iniate bluetooth module.");
            }
        }

        public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass cod) {
            try{
 		   discoveryForm.append("\nfound: " + remoteDevice.getFriendlyName(true));
            } catch(Exception e){
               discoveryForm.append("\nfound: " + remoteDevice.getBluetoothAddress());
            } finally{
		   remoteDevices.addElement(remoteDevice);
		}
        }

        public void inquiryCompleted(int discType) {

            if (remoteDevices.size() > 0) {

                // the discovery process was a success
                // so let's out them in a List and display it to the user
                for (int i=0; i<remoteDevices.size(); i++){
                    try{
                       devicesList.append(((RemoteDevice)remoteDevices.elementAt(i)).getFriendlyName(true), bt_logo);
                    } catch (Exception e){
                       devicesList.append(((RemoteDevice)remoteDevices.elementAt(i)).getBluetoothAddress(), bt_logo);
                    }
                }
                display.setCurrent(devicesList);
            } else {
			// no devices found in range
            discoveryForm.append("\nNo Devices Found.");
		}
        }
  
// program gets connection data here
        public void run(){
            try {
                // picks selected device
                RemoteDevice remoteDevice = (RemoteDevice)remoteDevices.elementAt(devicesList.getSelectedIndex());
                // gets Bluetooth address, and creates connection URL in format:
                // btspp://[Insert Bluetooth address here]:1;authenticate=false;encrypt=false;master=false
                btConnectionURL = "btspp://" + remoteDevice.getBluetoothAddress() + ":1;authenticate=false;encrypt=false;master=false";
                display.setCurrent(readyToConnectForm);
                readyToConnectForm.append("\n\nThe Bluetooth connection address is: " + remoteDevice.getBluetoothAddress());
            } catch(Exception e) {
            }
        }

        public void servicesDiscovered(int transID, ServiceRecord[] servRecord){
        }
        public void serviceSearchCompleted(int transID, int respCode) {

        }
   }

    /**
     * This is an inner class that is used for sending
     * the serial stream of data to a RFCOMM device
     *
     */
    class COMMReader extends Thread {

	public COMMReader() {

	}

	public void run(){

		try{
	    StreamConnection connection = (StreamConnection)Connector.open(btConnectionURL);
            OutputStream out = connection.openOutputStream();

          byte temp = 0;

            // sendData is set false by default and an Exit Command
			sendData = true;

            // everything RFCOM-wise happens in this while-loop
			while(sendData == true){

                // if new output data is available, send and write to form
                if (outSerial[0] != temp){
                   temp = outSerial[0];
                   out.write(outSerial[0]);
                    out.flush();
                    serialView_out = Integer.toBinaryString(outSerial[0]);
                }

                // refresh Canvas
                canvas.repaint();

			}

			connection.close();

		}catch(IOException ioe){
		}
	}
    }

       /**
        * This is an inner class used for making a canvas to
        * display serial I/O and process keypad changes
        */

    class KeyCodeCanvas extends Canvas{

        byte star_stat = 0;
        byte zero_stat = 0;
        byte square_stat = 0;

        public KeyCodeCanvas(){
        }

        protected void paint(Graphics g) {

            // Clear the background (to white)
            g.setColor(255,255,255);
            g.fillRect(0, 0, getWidth(), getHeight());

            // draws data strings
            g.setColor(0,0,255);
            g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_LARGE));
            g.drawString(serialView_out, 165, 65, Graphics.RIGHT|Graphics.BASELINE);

            // Covers little error area from bytes over 7 bits. ;-)
            g.setColor(255,255,255);
            g.fillRect(0, 0, 85, getHeight());

            // write title and labels
            g.setColor(0,0,0);
            g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE));
            g.drawString("Serial I/O:", (getWidth()/2), 25, Graphics.HCENTER|Graphics.BASELINE);
            g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_UNDERLINED, Font.SIZE_LARGE));
            g.drawString("Output:", 15, 65, Graphics.LEFT|Graphics.BASELINE);

            // draws button status strings
            g.setColor(0,0,0);
            g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM));
            g.drawString(buttonID, (getWidth()/2), 105, Graphics.HCENTER|Graphics.BASELINE);
            g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_LARGE));
           // g.drawString(HDLED, 20, 135, Graphics.LEFT|Graphics.BASELINE);
           // g.drawString(BRKLED, 20, 155, Graphics.LEFT|Graphics.BASELINE);

        }

        protected void keyPressed(int keyCode){

            /* works from 0 to 0b1111111
            outSerial={127,63,31,15,7,3,1,0};*/

             switch (keyCode){
                 case KEY_NUM2: {
                     outSerial[0] = (byte) (127);
                     buttonID = "Forward";
                     break;
                 }
                 case KEY_NUM5: {
                     outSerial[0] = (byte) (63);
                     buttonID = "Rewind";
                     break;
                 }
                 case KEY_NUM4: {
                     outSerial[0] = (byte) (31);
                     buttonID = "LEFT";
                     break;
                 }
                 case KEY_NUM6: {
                     outSerial[0] = (byte) (15);
                     buttonID = "RIGHT";
                     break;
                 }
                 case KEY_NUM0: {
                     outSerial[0] = (byte) (7);
                     buttonID = "STOP";
                     break;
                 }    
              }
             // display change in I/O
             canvas.repaint();
         }
      
    }
}
код я использовал из этого проекта, с небольшими правками.
http://uzzors2k.4hv.org/index.php?page=blucar
Очень удобно что телефон ищет сам окружающие устройства - не надо вводить адрес вручную.
Код для Ардуино

Код: Выделить всё

int pwm_a = 3;  
int pwm_b = 11;  
int dir_a = 12;  
int dir_b = 13;  
byte val;        

void setup()
{
  Serial.begin(9600);              
  pinMode(pwm_a, OUTPUT);         
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_a, OUTPUT);
  pinMode(dir_b, OUTPUT);

  analogWrite(pwm_a, 0);  
  analogWrite(pwm_b, 0);
}

void loop()
{
  if (Serial.available()) 
  {       
    val = Serial.read();  
    
    if (val == B1111111) {
      digitalWrite(dir_a, 1);digitalWrite(dir_b, 1);
      analogWrite(pwm_a, 255);analogWrite(pwm_b, 255); //forward
      };
    
    if (val == B111111) {
      digitalWrite(dir_a, 0);digitalWrite(dir_b, 0);
      analogWrite(pwm_a, 255);analogWrite(pwm_b, 255); //backward
      };
    
    if (val == B111) {
        analogWrite(pwm_a, 0);analogWrite(pwm_b, 0); };//stop
           
    if(val == B11111) {
      
      analogWrite(pwm_a, 0);analogWrite(pwm_b, 255);};     //left
    
    if(val == B1111){
    
    analogWrite(pwm_a, 255);analogWrite(pwm_b, 0);};       //right
        
  }
}
Управление кнопками "2" - вперед,"5"- назад, "4"- влево, "6" -вправо, "0"- стоп
Видео запуска

Хороший учебник по Java на сайте ibm
http://www.ibm.com/developerworks/ru/edu/j-introtojava1
и по Java Me
http://www.ibm.com/developerworks/ru/ed ... tion3.html
могу выложить jar.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение Mr.Kubikus »

Серьезная работа. Поздравляю с успехом! В какой среде писали программу?

JAR можно приаттачить к предыдущему сообщению в виде zip архива .
С уважением, Григорий
GitHub FB ВК
serg
Сообщения: 17
Зарегистрирован: 27 мар 2013, 16:18

Re: Управление Arduino по Bluetooth с мобильного телефона

Сообщение serg »

Сложно было проверять найденные коды на себе (не зная Java). Писал в NetBeans- среда очень легко настраивается под мобильные приложения. Пробовал Eclipse - совсем не то. Наверное потому что пытался сразу подключить SDK Nokia конкретной платформы. IntelliJ - не смог запустить под Java ME. Думаю, что надо было писать на Mobile Processing - все таки одно и тоже с Arduino.
Вложения
blue_tank.zip
(17.94 КБ) 1097 скачиваний
Ответить