It is time for fun. If you accepted that
using Android phone to control hardware is fun:) Android become very
popular and if you into microcontrollers it is pity not to use that
knowledge for making cool applications. If you experienced with
microcontrollers it is useful to expend your knowledge with any object
oriented language. That can be useful for future job opportunities. For
Android you need to know Java programming and usage of Eclipse IDE for
Java developers. Maybe sounds hard, but today there are a lot of free
online courses about Android and plenty of examples and complete
projects.
Here are picture and video of complete hardware:
For this project we make new hardware.
Microntroller dsPIC30F4013 was used and Microelektronika microBUS is
implemented. USB power supply makes device easy to use. Note: On
schematic as voltage regulator TS2940 is used, not BA33BC0FP. Our goal
is to make new projects using Mikroelektronika click boards. This is our
first project with this hardware. Complete schematics is given at
picture, an if you want to make your own board just contact us.
Android application description. We wanted to use Bluetooth click and Android phone to control LEDs tied on dsPIC microcontroller. As inspiration we examine project at Karel Blogs
and we want to gratitude for sharing this excellent project. Remember
that we are not Android experts but with this project we managed to make
things works (hooray). Adopted android application when receive any
character from dsPIC (via Bluetooth), sends array of character according
to ImageButton states. Application has four ImageButton for different
color of LED (see picture) and "connect" button for making Bluetooth
connection. When connect button is pressed, new activity (view) appeared
with saved and available Bluetooth devices (2nd view on picture). If
Bluetooth on device is off, dialog will appear to ask you to turn it on.
Than you can choose device and make connection. If you use
Mikroelektronika Bluetooth Click module, you have to enter default
passkey (1234).
If you accepted that Karel's code works
fine (as we did), we only need to change main class and main xml file.
Here is code for BluetoothLEDControl class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
| /* * Copyright 2011 Karel Bruneel (www.karelbruneel.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package electronics.base.com.btledctrl;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageButton;import android.widget.TextView;public class BluetoothLEDControl extends Activity implements BluetoothSPPConnectionListener { private static final int REQUEST_CONNECT_DEVICE = 1; private static final int REQUEST_ENABLE_BT = 2; private BluetoothSPPConnection mBluetoothSPPConnection; private BluetoothAdapter mBluetoothAdapter = null; private boolean connected = false; private byte gravity[]; private ImageButton imageButton1, imageButton2, imageButton3, imageButton4; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_led_panel); // Initializing the gravity vector to zero. gravity = new byte[4]; gravity[0] = 'a'; gravity[1] = 'c'; gravity[2] = 'e'; gravity[3] = 'g'; imageButton1 = (ImageButton) findViewById(R.id.imageButton1); imageButton1.setImageResource(R.drawable.led_red_gray); imageButton1.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (gravity[0] == 'a') { gravity[0] = 'b'; imageButton1.setImageResource(R.drawable.led_red); } else { imageButton1.setImageResource(R.drawable.led_red_gray); gravity[0] = 'a'; } } }); imageButton2 = (ImageButton) findViewById(R.id.imageButton2); imageButton2.setImageResource(R.drawable.led_green_gray); imageButton2.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (gravity[1] == 'c') { gravity[1] = 'd'; imageButton2.setImageResource(R.drawable.led_green); } else { gravity[1] = 'c'; imageButton2.setImageResource(R.drawable.led_green_gray); } } }); imageButton3 = (ImageButton) findViewById(R.id.imageButton3); imageButton3.setImageResource(R.drawable.led_blue_gray); imageButton3.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (gravity[2] == 'e') { gravity[2] = 'f'; imageButton3.setImageResource(R.drawable.led_blue); } else { gravity[2] = 'e'; imageButton3.setImageResource(R.drawable.led_blue_gray); } } }); imageButton4 = (ImageButton) findViewById(R.id.imageButton4); imageButton4.setImageResource(R.drawable.led_white_gray); imageButton4.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (gravity[3] == 'g') { gravity[3] = 'h'; imageButton4.setImageResource(R.drawable.led_white); } else { gravity[3] = 'g'; imageButton4.setImageResource(R.drawable.led_white_gray); } } }); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // If bluetooth is not activated, ask the user to activate if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } // Initializing the bluetooth SPP connection. // Register this as the BluetoothSPPConnectionListener. mBluetoothSPPConnection = new BluetoothSPPConnection(this); // Registers // the // Initializing the "connect" button. // Register this an the OnClickListener. Button bt = (Button) findViewById(R.id.connect); bt.setText("Connect"); bt.setOnClickListener(new OnClickListener() { public void onClick(View v) { // When not connected, start the MainActivity that allows // the user to select a device. // The activity will return a bluetoothdevice and on that // return, the onActivityResult() (see below) // member function is called. if (!connected) { Intent serverIntent = new Intent(v.getContext(), MainActivity.class); startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); // When connected, close the bluetooth connection. } else { mBluetoothSPPConnection.close(); } } }); } @Override protected void onDestroy() { super.onDestroy(); // Close the bluetooth connection mBluetoothSPPConnection.close(); } @Override protected void onPause() { super.onPause(); } public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CONNECT_DEVICE: if (resultCode == Activity.RESULT_OK) { String address = data.getExtras().getString( MainActivity.EXTRA_DEVICE_ADDRESS); BluetoothDevice device = mBluetoothAdapter .getRemoteDevice(address); mBluetoothSPPConnection.open(device); } break; case REQUEST_ENABLE_BT: if (resultCode == Activity.RESULT_OK) { } break; } } public void bluetoothWrite(int bytes, byte[] buffer) { byte[] command = new byte[5]; command[0] = 'y'; command[1] = gravity[0]; command[2] = gravity[1]; command[3] = gravity[2]; command[4] = gravity[3]; mBluetoothSPPConnection.write(command); } public void onConnecting() { // This function is called on the moment the phone starts making a // connecting with the bluetooth module. // The function is executed in the main thread. // Change the text in the connectionInfo TextView TextView connectionView = (TextView) findViewById(R.id.connectionInfo); connectionView.setText("Connecting..."); } public void onConnected() { // This function is called on the moment a connection is realized // between the phone and the bluetooth module. // The function is executed in the main thread. connected = true; // Change the text in the connectionInfo TextView TextView connectionView = (TextView) findViewById(R.id.connectionInfo); connectionView.setText("Connected to " + mBluetoothSPPConnection.getDeviceName()); // Change the text in the connect button. Button bt = (Button) findViewById(R.id.connect); bt.setText("Disconnect"); // Send the 's' character so that the communication can start. byte[] command = new byte[1]; command[0] = 's'; mBluetoothSPPConnection.write(command); } public void onConnectionFailed() { // This function is called when the intended connection could not be // realized. // The function is executed in the main thread. connected = false; // Change the text in the connectionInfo TextView TextView connectionView = (TextView) findViewById(R.id.connectionInfo); connectionView.setText("Connection failed!"); // Change the text in the connect button. Button bt = (Button) findViewById(R.id.connect); bt.setText("Connect"); } public void onConnectionLost() { // This function is called when the intended connection could not be // realized. // The function is executed in the main thread. connected = false; // Change the text in the connectionInfo TextView TextView connectionView = (TextView) findViewById(R.id.connectionInfo); connectionView.setText("Not Connected!"); // Change the text in the connect button. Button bt = (Button) findViewById(R.id.connect); bt.setText("Connect"); }} |
Logic is quite simple, we use byte array
to store ASCI characters and ImageButtons to change those characters.
For example, character 'a' means that red LED is off and 'b' means LED
is on (lines 51 and 55). You are right, not briliant logic but very
educational :). You can notice that we change pictures of buttons for
visual interpretation. "Off" picture is gray-scaled. Rest of code is
kind a copy of original project. You can download complete BluetoothLEDControl project to learn more about Android programming. Our test application is available HERE.
Hardware realization. Schematic of hardware is given above. First we need to setup Bluetooth module. After reading datasheet of RN41 Bluetooth module, we realized that GPIO7 and GPIO3 must be shortened as it shown on picture.
GPIO7 when high force baud rate of 9600,
GPIO3 when high autodiscovery option is enabled. UART2 of dsPIC is used
for communication with Bluetooth module. In infinite loop, character
'a' is send to Android to trigger sending array of character from
Android phone. Download complete MPLAB project, here is main.c code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
| #include<p30fxxxx.h>#include <string.h>#include <delay.h>#include <libpic30.h>#include "uart.h"#include "timer.h"_FOSC(CSW_FSCM_OFF & FRC_PLL4); //7.37 MHz Internal RC oscillator, 4x PLL enabled_FWDT(WDT_OFF); //Watchdog disabled#define DELAY_RANDOM 3000000#define RXbuffLen 16int tempRX, tempRX2;char buf[10];char uartRXbuffer[RXbuffLen];int tempUART;char received;unsigned int stopwatch;//-----------------------------------------------------------------void __attribute__((__interrupt__)) _U1RXInterrupt(void){ IFS0bits.U1RXIF = 0; tempRX = U1RXREG;}void __attribute__((__interrupt__)) _U2RXInterrupt(void) { IFS1bits.U2RXIF = 0; tempRX2 = U2RXREG; for (tempUART = 0; tempUART < RXbuffLen; tempUART++) { uartRXbuffer[tempUART] = uartRXbuffer[tempUART + 1]; } uartRXbuffer[RXbuffLen - 1] = tempRX2; //put character in array (backward) if (tempRX2 != '0') { received = 1; //flag in on - something was received }}void __attribute__((__interrupt__)) _T1Interrupt(void) // TIMER INTERRUPT//-----------------------------------------------------------------{ TMR1 = 0; //Stop Timer stopwatch++; //for Delay_ms() function IFS0bits.T1IF = 0; //Clear timer flag}//-----------------------------------------------------------------//-----------------------------------------------------------------void Delay_ms(unsigned int time)//-----------------------------------------------------------------// funkcija za kasnjenje u ms{ stopwatch = 0; while(stopwatch < time);}void ClearBuffer() { unsigned char priv; for (priv = 0; priv < RXbuffLen; priv++) { uartRXbuffer[priv] = '0'; }}int main(void){ InitUART1(); InitUART2(); Init_T1(); received=0; ClearBuffer(); ADPCFGbits.PCFG10=1; //Pin RB10 digital TRISBbits.TRISB10=0;// PB10 output LATBbits.LATB10 = 1; ADPCFGbits.PCFG0=1; // Pin RB0 digital TRISBbits.TRISB0=0; // PB0 output LATBbits.LATB0 = 1; ADPCFGbits.PCFG2=1; // Pin RB2 digital TRISBbits.TRISB2=0; // PB2 output LATBbits.LATB2 = 1; ADPCFGbits.PCFG4=1; // Pin RB4 digital TRISBbits.TRISB4=0; // PB4 output LATBbits.LATB4 = 1; WriteStringUART1("Start"); WriteUART1(13); while (1) { WriteStringUART1("Sending to module\r"); WriteUART2(97); //Send to Bluetooth 'a' character to trigger sending from Android phone if(received == 1) { //WriteStringUART1("Received: "); received = 0; //reset flag //WriteStringUART1(uartRXbuffer); //UART buffer //WriteUART1(13); //WriteUART1(uartRXbuffer[13]); //Test what is on 13th position in buffer //WriteUART1(13); if(uartRXbuffer[12] == 'b') { LATBbits.LATB2 = 0; //red LED on } if(uartRXbuffer[12] == 'a') { LATBbits.LATB2 = 1; //red LED off } if(uartRXbuffer[13] == 'd') { LATBbits.LATB4 = 0; } if(uartRXbuffer[13] == 'c') { LATBbits.LATB4 = 1; } if(uartRXbuffer[14] == 'f') { LATBbits.LATB0 = 0; } if(uartRXbuffer[14] == 'e') { LATBbits.LATB0 = 1; } if(uartRXbuffer[15] == 'h') { LATBbits.LATB10 = 0; } if(uartRXbuffer[15] == 'g') { LATBbits.LATB10 = 1; } ClearBuffer(); } Delay_ms(500); //for faster response you can decrease delay }//while return 0;}//main |
No comments:
Post a Comment