Доброго времени суток!
Решил перенести управление бульдозером 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;
}
}
Код для Ардуино, который вы привели, похож на заготовку без конкретного наполнения. В частности, функция, которая отвечает за разбор пакета данных, полученного через 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:
Мое приложение может не запускаться на вашем Nokia 5130 потому что я разрабатывал его для ОС Symbian v9.1 и платформы S60 3rd Edition (initial release).
Я знал что Nokia 5500 sport работает под Symbian. Непонятно почему в Eclipse запускается только один RoboTXControl.java. А при запуске всего проекта выдается ошибка.
Сначала поставил Eclipse Indigo и Nokia SDK для своего телефона (да и из любопытства скачал для всех телефонов S40). Потом скачал с сайта Nokia новый SDK с встроенным Indigo. Ошибка одна и та же. Я не ожидал что Java ME для Nokia Symbian настолько отлтичается от Java Me для Nokia S40. Какая библиотека в файле ControlCanvas.java так изменилась за прошедшие годы?
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
Очень удобно что телефон ищет сам окружающие устройства - не надо вводить адрес вручную.
Код для Ардуино
Сложно было проверять найденные коды на себе (не зная Java). Писал в NetBeans- среда очень легко настраивается под мобильные приложения. Пробовал Eclipse - совсем не то. Наверное потому что пытался сразу подключить SDK Nokia конкретной платформы. IntelliJ - не смог запустить под Java ME. Думаю, что надо было писать на Mobile Processing - все таки одно и тоже с Arduino.