use char as an operator? - android

I am making an android app + arduino that will receive ir code from arduino and sending the results.value (ir decode) to android through bluetooth. on the android side I have receive the code as a String that results into (for example) 92c0 then made a test button that will send it back to arduino and trigger it to send ir code to a device by irsend.sendNEC(0x92c0, 32) problem is when receiving the codes back from the android app is I have to receive it by char data, how do I use data which is a char and use it as a substitute for 0x92c0 in irsend.sendN My sketch down below:
#include <IRremote.h>
#include <SoftwareSerial.h>
SoftwareSerial bluetoothPort(4,5);
const int RECV_PIN = 12;
char data = "0";
const int SEND_PIN = 13;
IRsend irsend;
IRrecv irrecv(RECV_PIN);
decode_results results;
int BTval;
int IRval;
void setup()
{
bluetoothPort.begin(9600);
Serial.begin(9600);
irrecv.enableIRIn();
}
void loop()
{
if(bluetoothPort.available() > 0)
{
data = bluetoothPort.read();
Serial.print(data);
irsend.sendNEC(operator[data],32);
irrecv.resume();
}
if(irrecv.decode(&results))
{
Serial.println(results.value);
int set = results.value;
bluetoothPort.println(results.value, HEX);
irrecv.resume();
}
}

The problem here is that you CAN'T transfer 0x92c0 as a char (or byte). Just because it is not a byte, but two.
Now, I'm not much into android, so I need to see the android code to make a real solution You can handle this in three ways:
Binary transfer the data (2 bytes)
Transfer the data as a string (5 bytes)
Index the possible replies in an array and transfer the index (only applicable for a small quantity of codes).
I'm showing you the last 2, because the 1st is the most effective but I don't think you have the proper knowledge to send and receive data in binary format from android (and surely I don't have it).
So, if the data is transferred in string format (the same way you are uploading it) you will receive more bytes:
1 to 4 hexadecimal digits
1 carriage return
The code just stores the bytes you receive in a variable and then sends it when you receive a CR or LF:
// Outside the loop function
uint16_t receivedData;
// Inside the loop function
if(bluetoothPort.available() > 0)
{
data = bluetoothPort.read();
if ((data >= '0') && (data <= '9'))
{ // If it is a digit between 0 and 9 (in ascii)
receivedData = (receivedData << 4) | (data - '0');
}
else if ((data >= 'A') && (data <= 'F'))
{ // If it is a digit between A and F (in ascii)
receivedData = (receivedData << 4) | (data - 'A' + 10);
}
else if ((data >= 'a') && (data <= 'f'))
{ // Lowercase case
receivedData = (receivedData << 4) | (data - 'a' + 10);
}
else if (((data == '\r') || (data == '\n')) && (receivedData > 0))
{ // I tend to consider both CR and LF, because windows always screws this
Serial.print(receivedData, HEX);
irsend.sendNEC(receivedData,32); // Not sure about the 32 here...
irrecv.resume();
receivedData = 0;
}
else
receivedData = 0; // Something went wrong, just reset the variable
}
If you just have to send a few codes, you can store them and then transfer only the proper index. For instance:
// Outside the loop function
uint16_t possibleCodes[] = { 0x92c0, 0x8238, 0x5555 };
// Inside the loop function
if(bluetoothPort.available() > 0)
{
data = bluetoothPort.read();
// If you are using string transmission, use the following
// line to get the correct value
// data = bluetoothPort.read() - '0';
if (data < sizeof(possibleCodes) / sizeof(possibleCodes[0]))
{
Serial.print(possibleCodes[data], HEX);
irsend.sendNEC(possibleCodes[data],32); // Not sure about the 32 here...
irrecv.resume();
}
}
For instance in this case to send 0x92c0 you will have to send from android the value 0.

Related

Communicating with Nexus-4 using libusb in firmware update mode

I am trying to develop a simple program to communicate with the Nexus-4 bootloader in firmware update mode.
Nexus -4 has three usb interfaces. Interface-1 has two 2 endpoints - 2 and 131.
I wrote a program to write the command, get-device-info, through endpoint 2 and listen at endpoint 131 for the reply.
(I tried all permutations of interfaces and endpoints!).
The program successfully writes the command to the device but nothing is read from the device.
Command format: Flag(0x7e): CMD: Data (variable length): CRC-16: Flag(0x7e)
Get-device-info-command: 0x7e 0x00 0x78 0xf0 0x7e
The following is the program.
#include <stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
#define INTERFACE 1
#define EP_OUT 2
#define EP_IN 131
int main() {
libusb_device **devs; // retrieve a list of devices
libusb_device_handle *dev_handle; // device handler
libusb_context *ctx = NULL; //a libusb session
int r, r2, i;
ssize_t cnt; //holding number of devices in list
unsigned char data[30],read_data[512]; //data to write
data[0]=0x7e;data[1]=0x00;data[2]=0x78;data[3]=0xf0;data[4]=0x7e; // get-device-info command in HLDC format
int actual,read_actual;
r = libusb_init(&ctx);
if(r < 0) {
printf("Init Error\n");
return 1;
}
libusb_set_debug(ctx, 3);
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
printf("Get Device Error\n");
return 1;
}
printf("%d Devices in list\n",(int)cnt);
dev_handle = libusb_open_device_with_vid_pid(ctx, 4100, 25371); //these are vendorID and productID I found for Nexus-4 firmware update
if(dev_handle == NULL)
printf("Cannot open device\n");
else
printf("Device opened\n");
libusb_free_device_list(devs, 0); //free the device list
if(libusb_kernel_driver_active(dev_handle, INTERFACE) == 1) { //find out if kernel driver is attached
printf("Kernel Driver Active\n");
if(libusb_detach_kernel_driver(dev_handle, INTERFACE) == 0) //detach it
printf("Kernel Driver Detached!\n");
}
r = libusb_claim_interface(dev_handle, INTERFACE); //claim interface 1 Nexus-5/4 FUM
if(r < 0) {
printf("Cannot Claim Interface\n");
printf("%s\n",libusb_error_name(r));
return 1;
}
printf("Claimed Interface\n");
printf("Data to be send -> %s\n",data); //just to see the data that we are writing
printf("Writing Data...\n");
r = libusb_bulk_transfer(dev_handle, (EP_OUT | LIBUSB_ENDPOINT_OUT), data, 5, &actual, 0);
if(r == 0 && actual == 5){ //we wrote successfully 5 bytes to the device
printf("Writing Successful!\n");
printf("Waiting to read from device!\n");
r2 = libusb_bulk_transfer(dev_handle, (EP_IN | LIBUSB_ENDPOINT_IN), read_data, 512, &read_actual, 5000);
if (r2 >=0){
if (read_actual > 0){
printf("Data received by bulk transfer\n");
printf("Data is ");
for (i=0; i<read_actual; i++)
printf("%x ",read_data[i]);
printf("\n");
}
else{
printf(stderr, "No data received in bulk transfer (%d)\n", r2);
return -1;
}
}
else{
fprintf(stderr, "Error receiving data via bulk transfer %d\n", r2);
return r2;
}
}
else
printf("Write Error\n");
r = libusb_release_interface(dev_handle, INTERFACE); //release the claimed interface
if(r!=0) {
printf("Cannot Release Interface\n");
return 1;
}
printf("Released Interface\n");
libusb_close(dev_handle);
libusb_exit(ctx);
return 0;
}
The program is able to send the command successfully to the phone but it is not able to receive any response from the phone. When I run the program, I get the following output:
10 Devices in list
Device opened
Kernel Driver Active
Kernel Driver Detached!
Claimed Interface
Data to be send -> ~
Writing Data...
Writing Successful!
Waiting to read from device!
Error receiving data via bulk transfer -7
I am not sure the reason for not getting a response is because of the wrong command structure or because of the implementation of the program?

Arduino - Converting byte array to string/char array

I'm currently working on communication between devices using HID over a usb cable. I am sending a string that is UTF-8 encoded from an Android device, and would like to receive and read it on my Arduino Leonardo.
My problem is that I am unable to get the received message into any other type. I need to do a human readable string comparison as I'm sending a variety of commands to the Arduino. The IDE either has a type mismatch problem regardless of how I try to convert the received message. I've tried many different things but I will post one as an example. I'm sure there is something I missing that's keeping me from getting this!
int n;
n = RawHID.recv(buffer, 0); // 0 timeout = do not wait
if (msUntilNextSend > 2000) {
msUntilNextSend = msUntilNextSend - 2000;
// String mystr = "";
// byte charbuff[10];
//
// for (int i = 0; i < 64; i++)
// {
// mystr.concat((char) buffer[i]);
// }
//
// mystr.toCharArray(charbuff, 10);
char readin[64] = { ' ' };
readin = (char *)buffer;
String myString = String((char *)buffer);
if (strcmp(readin, "test") == 0)
{
String resp = "response";
resp.getBytes(buffer, 64);
n = RawHID.send(buffer, 100);
}
I've included some comments with bits of a different approach but as I mentioned, I have been unsuccessful in my attempts. Any insight is appreciated!

Problems using and LDR to play Audio from SD card

I've hit a bit of a roadblock with my project. I've tried for hours and can't seem to find out what is causing my problem.
I'm trying to create a box that, when it's closed I can use bluetooth commands and arduino will play a response.
When you open the box, it will play a unique audio clip.
The problem is, the LDR works fine as in the unique clip plays whenever I open the box, however when the box is closed, the bluetooth responses don't play as expected, they just play a tiny snippet of the unique response from when it's open?
So once I open the box, the unique clip plays and the bluetooth responses work as expected.
I've tried using switch cases and for loops but to no avail.
Your help will be much appreciated!
//Coded By: Angelo Casimiro (4/27/14)
//Voice Activated Arduino (Bluetooth + Android)
//Feel free to modify it but remember to give credit
//PCM library used to turn voice file into a string of text for the speaker.
//Credit to HighTechLowTech
#include <SD.h> // need to include the SD library
//#define SD_ChipSelectPin 53 //example uses hardware SS pin 53 on Mega2560
#define SD_ChipSelectPin 4 //using digital pin 4 on arduino nano 328, can use other pins
#include <TMRpcm.h> // also need to include this library...
#include <SPI.h>
TMRpcm tmrpcm; // create an object for use in this sketch
int ldrPin = A2; //declared LDR on analog pin 2
int ldrValue = 0; //reading different values from the LDR
//declare voice as a string of data
String voice;
void setup() {
//Speaker pin
tmrpcm.speakerPin = 9;
Serial.begin(9600);
if (!SD.begin(SD_ChipSelectPin)) { // see if the card is present and can be initialized:
Serial.println("SD fail");
return; // don't do anything more if not
}
}
//-----------------------------------------------------------------------//
void loop() {
while (Serial.available()){ //Check if there is an available byte to read
delay(50); //Delay added to make thing stable
char c = Serial.read(); //Conduct a serial read
if (c == '#') {break;} //Exit the loop when the # is detected after the word
voice += c; //Shorthand for voice = voice + c
}
if (voice.length() > 0) {
Serial.println(voice);
}
//LDR variable defined from analog pin 2
ldrValue = analogRead(ldrPin);
//define LDR value ranges and map them to cases
//if voice string is "marco" then playback the sample array
if(voice == "*marco") {tmrpcm.play("Polo!.wav");}
else if(voice == "*hello") {tmrpcm.play("Hello!.wav");}
else if(voice == "*where") {tmrpcm.play("here.wav");}
else if(voice == "*who") {tmrpcm.play("Scott.wav");}
else if(voice == "*knock knock") {tmrpcm.play("Who.wav");}
else if(ldrValue > 500) {tmrpcm.play("Burp.wav");}
voice="";
delay(1);
}
It might be easier to see in this sketch using switch cases.
Basically, when the box is closed i can see in the serial monitor that case 2 is active which is what I want.
When the box is open, case 1 is active, but it's not playing 'Burp.wav' until I close it again and it switches back to case 2
//Coded By: Angelo Casimiro (4/27/14)
#include <SD.h> // need to include the SD library
//#define SD_ChipSelectPin 53 //example uses hardware SS pin 53 on Mega2560
#define SD_ChipSelectPin 4 //using digital pin 4 on arduino nano 328, can use other pins
#include <TMRpcm.h> // also need to include this library...
#include <SPI.h>
TMRpcm tmrpcm; // create an object for use in this sketch
//declare voice as a string of data
String voice;
//LDR value Range
const int sensorMin = 100;
const int sensorMax = 480;
void setup()
{
//Speaker pin
tmrpcm.speakerPin = 9;
Serial.begin(9600);
if (!SD.begin(SD_ChipSelectPin))
{
// see if the card is present and can be initialized:
Serial.println("SD fail");
return; // don't do anything more if not
}
}
//-----------------------------------------------------------------------//
void loop()
{
while (Serial.available())
{
//Check if there is an available byte to read
delay(50); //Delay added to make thing stable
char c = Serial.read(); //Conduct a serial read
if (c == '#')
{
break; //Exit the loop when the # is detected after the word
}
voice += c; //Shorthand for voice = voice + c
}
if (voice.length() > 0)
{
Serial.println(voice);
}
//LDR variable defined from analog pin 2
int sensorReading = analogRead(A2);
Serial.println(sensorReading);
//define LDR value ranges and map them to cases
int range = map(sensorReading, sensorMin, sensorMax, 1, 2);
Serial.println(range);
switch (range)
{
case 1:
{
tmrpcm.play("Burp.wav");
}
break;
case 2:
//if voice string is "marco" then playback the sample array
if (voice == "*marco")
{
tmrpcm.play("Polo!.wav");
}
else if (voice == "*hello")
{
tmrpcm.play("Hello!.wav");
}
else if (voice == "*where")
{
tmrpcm.play("here.wav");
}
else if (voice == "*who")
{
tmrpcm.play("Scott.wav");
}
else if (voice == "*knock knock")
{
tmrpcm.play("Who.wav");
}
voice = "";
break;
}
delay(50);
Serial.println();
}

Fastest way to read and parse ascii file from sdcard

I am working on an app that will allow the user to select an ascii text file (typically from the sdcard) that contains the data required to render a shape in opengl. The file format looks something like this (there are some other lines containing less relevant data):
normal -1.000000e+000 -5.551115e-016 0.000000e+000
vertex 1.387779e-014 0.000000e+000 1.000000e+001
vertex 0.000000e+000 2.500000e+001 1.000000e+001
vertex 1.387779e-014 0.000000e+000 0.000000e+000
The typical file could be around 5mb and contains around 120,000+ lines of data. I have tried several approaches to reading and parsing the file and I can't seem to get it to read the file and parse the data in less than about 90 seconds - which is obviously slower than I would like.
I have tried three approaches:
1) I read the file line by line and used the string split method with space as the delimiter
2) I then tried using the streamtokenizer to create a list of tokens (strings) for each word/number in the file. I then went through the list, filling arraylists with the data I needed (the numbers for the vertices in one list and the numbers for the normals in another). Again, this worked but was slow. Relevant blocks of code:
File f = new File(Environment.getExternalStorageDirectory()+"/"+filename);
int fLen = (int)f.length();
Log.d("msg:", "File contains " + fLen + " Characters");
try {
FileReader file = new FileReader(f);
buf = new BufferedReader(file);
FileParser st = new FileParser(buf);
while (st.nextToken() != st.TT_EOF) {
if (st.ttype==st.TT_WORD){
if (st.sval.equals("vertex"))
{
st.nextToken();
vertices.add((Double.valueOf(st.sval).floatValue()));
st.nextToken();
vertices.add((Double.valueOf(st.sval).floatValue()));
st.nextToken();
vertices.add((Double.valueOf(st.sval).floatValue()));
indices.add((short)(nodeCount-1));
}
}
}
The streamtokenizer is initialized as follows:
public class FileParser extends StreamTokenizer
{
public FileParser(Reader r)
{
super(r);
setup();
}
public void setup()
{
resetSyntax();
eolIsSignificant(true);
lowerCaseMode(true);
wordChars('!', '~');
whitespaceChars(' ', ' ');
whitespaceChars('\n', '\n');
whitespaceChars('\r', '\r');
whitespaceChars('\t', '\t');
}// End setup
}
3) Based on an article I read about counting words in a text file that said that streamtokenizers are slow compared to using a char buffer, I tried reading the file into a large char buffer (in chunks where necessary). I saw some improvement but only maybe 20%. Relevant code:
FileReader file = new FileReader(f);
char pos = "+".charAt(0);
char neg = "-".charAt(0);
char dec = ".".charAt(0);
float[] normalVector=new float[3];
int bufSize=500000;
int offset=0;
char[] buffer=new char[bufSize];
while ((len=file2.read(buffer,offset,bufSize-offset)) != -1) {
index=0;
while (index < len+offset) {
while ((index < (len+offset)) && !Character.isLetterOrDigit(buffer[index]) && !(buffer[index]==pos) && !(buffer[index]==neg) && !(buffer[index]==dec)) {
index++;
if ((index>bufSize-20)&&(len+offset==bufSize)) {
offset=len+offset-index;
for(int i=0; i<offset; i++){
buffer[i]=buffer[index+i];
}
index=len+offset;
}
}
start = index;
while ((index < (len+offset)) && ((Character.isLetterOrDigit(buffer[index]) || buffer[index]==pos || buffer[index]==neg) || buffer[index]==dec)) {
index++;
}
if (start < (len+offset)) {
text = String.copyValueOf(buffer, start, index-start);
if (text.equals("vertex")) {
xyz=1;
} else if (xyz>0) {
vertices.add((Double.valueOf(text).floatValue()));
xyz=xyz+1;
if (xyz==4){
nodeCount++;
indices.add((short)(nodeCount-1));
xyz=0;
}
}
}
}
}
There must be some sort of bottleneck that I am missing. Any ideas?

how can I distinguish H264 encoded Video frames by some special tag?

I have H264 encoded Video file came from Android mobile camera and I want to get the frames and store them as files one by one. The problem is, how can I distinguish the frames, do the frames split up by some special tag? Now I have this function which can get the frames length by bytes, maybe it helps to understand my questions,Thx:)
public static int h263Parse(byte[]buf, int offset, int nLen)
{
int vop_found, i;
vop_found = 0;
i=0;
if(vop_found == 0)
{
for(i=(offset + 3); i<(offset+nLen); i++)
{
if(buf[i-3] == 0x00)
if(buf[i-2] == 0x00)
if((buf[i-1]&0xff) < 0x84)
if((buf[i-1]&0xff) >= 0x80)
{
i++;
vop_found=1;
break;
}
}
}
if(vop_found == 1)
{
for(; i<(offset+nLen); i++)
{
if(buf[i-3] == 0x00)
if(buf[i-2] == 0x00)
if((buf[i-1]&0xff) < 0x84)
if((buf[i-1]&0xff) >= 0x80)
{
return i-3-offset;
}
}
}
return -1;
}
I seriously don't know what your code is doing (because it is named h263parse) and you are asking about h264.
Anyways, H264 frames do split up by a special tag, called the startcode prefix, which is either of 0x00 0x00 0x01 OR 0x00 0x00 0x00 0x01
All the data between two startcodes comprises a NAL unit in H264 speak. So perhaps what you want to do is search for the startcode prefix in your h264 stream and do something with the NAL unit that follows (until the next startcode prefix) in the stream.
Something like this perhaps:
void h264parse_and_process(char *buf)
{
while(1)
{
if (buf[0]==0x00 && buf[1]==0x00 && buf[2]==0x01)
{
// Found a NAL unit with 3-byte startcode, do something with it
do_something(buf); // May be write to a file
break;
}
else if (buf[0]==0x00 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x01)
{
// Found a NAL unit with 4-byte startcode, do something with it
do_something(buf); // May be write to a file
break;
}
buf++;
}
}

Categories

Resources