I'm developing an app where I need to send 3 seekbar's values to a PCB via bluetooth. I've done all the bluetooth code based on the bluetoothchat example. I first modified it to send a string with these 3 values. But now, I need to do something more dificult and i don't know how to do it.
First of all, in the app i modify the seekbars and then i click on the send button. In the code, I need to set a string for each seekbar's value, because I need to access to the MCU variables and set each variable address, value, CRC etc...
So, I need to know the correct way to do this. Here is the code where i define the send function:
/**
* SEND THREAD
*/
/**[Start Thread + Send command + Nº bytes thread + Nº bytes variable + Address + Variable value + CRC]*/
public void sendValues() {
/**Set the seekbars values into a string*/
send_value1 = Integer.toString(savedProgress1);
send_value2 = Integer.toString(savedProgress2);
send_value3 = Integer.toString(savedProgress3);
String message1 = start_thread+" "+send_command+" "+num_byte_trama1+ " "+num_byte_variable+" "+pos_reg_1+" "+Value+" "+CRC;
String message2 = start_thread+" "+send_command+" "+num_byte_trama1+ " "+num_byte_variable+" "+pos_reg_2+" "+Value+" "+CRC;
String message3 = start_thread+" "+send_command+" "+num_byte_trama1+ " "+num_byte_variable+" "+pos_reg_3+" "+Value+" "+CRC;
String message4 = start_thread+" "+send_command+" "+num_byte_trama2+ " "+num_byte_variable+" "+pos_reg_save_request+" "+Value+" "+CRC;
String message5 = start_thread+" "+send_command+" "+num_byte_trama2+ " "+num_byte_variable+" "+pos_reg_save_status+" "+Value+" "+CRC;
/**Check that we're actually connected before trying anything*/
if (GlobalVar.mTransmission.getState() != GlobalVar.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
/**Get the message bytes and tell the Transmission to write*/
byte[] send = message.getBytes();
GlobalVar.mTransmission.write(send);
/**Reset out string buffer to zero*/
GlobalVar.mOutStringBuffer.setLength(0);
}
There are these few things that I ask you to help me:
1- Need to know how to calculate the CRC
2- I need to send these 5 strings together when pressing the send button.
In the part where i get the bytes to send, I don't know If the right way to do this would be to add these 5 strings on 1 and send this one (maybe it would be to long if I do this), or to create a function to send these 5 separately but at the same time.
This is the edited code to send each message one by one:
/**Conversion to decimal of the seekbar's % value*/
send_int1 = ((savedProgress1 * 20480) / 100) * -1;
send_int2 = ((savedProgress2 * 20480) / 100) * -1;
send_int3 = ((savedProgress3 * 20480) / 100) * -1;
/**Conversion to string of the previous values to send in the string message*/
sendValue1 = Integer.toString(send_int1);
sendValue2 = Integer.toString(send_int1);
sendValue3 = Integer.toString(send_int1);
String message1 = start_thread+" "+send_command+" "+num_byte_trama1+" "+num_byte_variable+" "+pos_reg_1+" "+sendValue1+" " ;
String message2 = start_thread+" "+send_command+" "+num_byte_trama1+" "+num_byte_variable+" "+pos_reg_2+" "+sendValue2+" " ;
String message3 = start_thread+" "+send_command+" "+num_byte_trama1+" "+num_byte_variable+" "+pos_reg_3+" "+sendValue3+" " ;
String message4 = start_thread+" "+send_command+" "+num_byte_trama2+" "+num_byte_variable+" "+pos_reg_save_request+" " ;
String message5 = start_thread+" "+send_command+" "+num_byte_trama2+" "+num_byte_variable+" "+pos_reg_save_status+" " ;
/**Check that we're actually connected before trying anything*/
if (GlobalVar.mTransmission.getState() != GlobalVar.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
/**Get the message bytes and tell the Transmission to write*/
byte[] send1 = message1.getBytes();
GlobalVar.mTransmission.write(send1);
//Wait untill I receive the confirmation from the MCU
byte[] send2 = message2.getBytes();
GlobalVar.mTransmission.write(send2);
byte[] send3 = message3.getBytes();
GlobalVar.mTransmission.write(send3);
byte[] send4 = message4.getBytes();
GlobalVar.mTransmission.write(send4);
byte[] send5 = message5.getBytes();
GlobalVar.mTransmission.write(send5);
/**Reset out string buffer to zero*/
GlobalVar.mOutStringBuffer.setLength(0);
}
For your frame, I recommand you to use this kind of frame :
final byte[] HEADER = AA11 // For example
// When you want to send a message :
Strign messageToSend = new String(HEADER) + yourStringMessage
It'll be easier for you to analyze the frame when you receive it.
Then, for the CRC, I can't answer if you don't tell the kind of CRC. In my app, I used
private static char createCRC(byte[] frame)
{
int crc = 0;
for(byte i : frame)
{
crc = crc^i;
}
return (char)crc;
}
to create the CRC by "XORing" each byte of my message , and then check a CRC is quite easy
UPDATE : Well, I finally get it.
In the BluetoothChat activity, you get a string version of message, and the byte[] one.
If you want to get the first byte of the message, just add byte myByte = readBuf[0] before String readMessage = new String(readBuf, 0, msg.arg1);
Then, String readMessage = new String(myByte, 0, msg.arg1);
Related
I make a POS project. I want to print receipt. I'm using thermal printer zonerich. I had successfully to print the receipt. Now, I want to custom the font. I want to make the outlet name bigger ,have a bold style and in center.
In my code bellow, when i try to put the bold format it will bold all of the receipt not only the outlet name. Please tell me how to make style only in outlet name and how to change the font size, Sorry for bad english. Thanks for your help.
public void IntentPrint(String notaID, String namaKasir, String date, String total, String pay, String change, String method) {
db = new DatabaseHandler(MainActivity.this);
String payment="";
String sosmed = "\n"+ sessionStartUp.getUserDetails().get(sessionStartUp.KEY_SOSMED);
String namaOtlet = sessionStartUp.getUserDetails().get(sessionStartUp.KEY_OUTLET);
String header ="\nReceipt : " + db.getFakeNotaID(notaID) + "\n" +
"Nama Kasir : " + namaKasir + "\n" +
"Date : " + date+"\n"+
"Name Qty Price"+"\n";
if(!pay.equals("0"))
{
payment ="\nTotal : "+total+"\n"+"Method : "+method+"\n"+
"Payment : "+pay+"\n"+
"Change : "+change;
}
else
payment ="\nTotal : "+total+"\n"+"\nMethod : "+method+"\n";
InitPrinter();
try {
outputStream.write(header.getBytes());
outputStream.write(data(notaID).getBytes());
outputStream.write(payment.getBytes());
outputStream.write(sosmed.getBytes());
byte[] format= { 27, 33, 0 };
byte[] center = { 0x1b, 'a', 0x01 };
byte[] arrayOfByte1 = { 27, 33, 0 };
format[2] = ((byte)(0x8 | arrayOfByte1[2]));
outputStream.write(center);
outputStream.write(format);
outputStream.write(namaOtlet.getBytes(),0,namaOtlet.getBytes().length);
outputStream.close();
socket.close();
} catch (Exception ex) {
value += ex.toString() + "\n" + "Excep IntentPrint \n";
// Toast.makeText(this, value, Toast.LENGTH_LONG).show();
}
}
In my app i send four basic commands to OBD ports and get back hex data...
I don't know why if i send the command:
ME: 010c
Car: 10c410c0000
Why the message don't start with 4?
And get only 410c and the data that the obd receive from car?
I use this method for manage hex response and convert it to human readable data, and RawData is a String that take the message and clear all space, like this
41 0c 00 00 = 410c0000
public String getCalculatedResult() {
//TODO devo convertire i dati da esadecimale a decimale ed effettuare i calcoli
int calculatedData = 0;
String dataToShow = null;
//Log.d("ObdCommand", "rawData: " + rawData.substring(3));
calculatedData = Integer.parseInt(rawData.substring(7), 16);
if (Pattern.compile(Pattern.quote(rawData.substring(3,4)),
Pattern.CASE_INSENSITIVE).matcher("410D").find()){
Log.d("ObdCommand", "dentro 410D: ");
//Velocità veicolo km/h
dataToShow = String.valueOf(calculatedData) + " Km/h";
Log.d("ObdCommand", "rawData: " + dataToShow);
}else if (Pattern.compile(Pattern.quote(rawData.substring(3,4)),
Pattern.CASE_INSENSITIVE).matcher("410C").find()){
Log.d("ObdCommand", "dentro 410C: ");
//Giri minuto veicolo rpm
calculatedData = calculatedData/4;
dataToShow = String.valueOf(calculatedData) + " rpm";
}else if (rawData.substring(3).startsWith("4105")){
//Temperatura refrigetante C°
calculatedData = calculatedData - 40;
dataToShow = String.valueOf(calculatedData) + " C°";
}else if (rawData.substring(3).startsWith("4151")){
//Tipo di carburante
if (rawData.substring(7).startsWith("09")){
//Benzina
dataToShow = "Benzina";
}else if (rawData.substring(7).startsWith("0d")){
//Metano
dataToShow = "Metano";
}
}
return dataToShow;
}
I use the rawData.substring(7) because 3 is the characters that i tell at the start of post
10c
And the other 4 are
410c
So i get only the value that i need to decimal... but sometimes i get outof bound....
Someone have some idea to get this with no problems?
Thanks
I have Android <-> Arduino bluetooth communication. Sometimes Android gets two messages instead of one from Arduino. What i mean: if i send for ex. 5 bytes message "1234" from Arduino to Android over bluetooth, sometimes i get "1" 1 byte in one message and "234"+\n 4 bytes in second message. Sometimes i get full "1234"+\n 5 byte message and do not have any clue why. I need to split input message by delimiter and if i get separate message i get crash. So i need to append bytes to string till new line char comes.
How to add chars to string till "\n" new line char comes?
Case when data comes:
case BLUETOOTH_RECEIVED:
byte[] buffer = (byte[])msg.obj;
int len = msg.arg1;
if (len > 0 && buffer != null) {
onBluetoothRead(buffer, len);
}
break;
}
buffer to string:
private void onBluetoothRead(byte[] buffer, int len) {
Log.i(LOGGER_TAG, String.format("Received: " + output.replace("\n", "") + " message of " + "%d bytes", len));
String output = new String(buffer, 0, len); // Add read buffer to new string
m_deviceOutput.append(output); // Add (not replace) string to TextView
StringTokenizer splitStr = new StringTokenizer(output, ","); // split string by comma
String numberOne = splitStr.nextToken(); // First split string
String numberTwo = splitStr.nextToken(); // Second split string
numberOne = numberOne.replaceAll("\\D+",""); // replace all chars, leave only numbers
numberTwo = numberTwo.replaceAll("\\D+","");
}
LogCat:
07-22 14:06:15.099: I/DeviceActivity(20370): Received: 1234 message of 5 bytes
07-22 14:06:20.599: I/DeviceActivity(20370): Received: 1234 message of 5 bytes
07-22 14:06:27.349: I/DeviceActivity(20370): Received: 1 message of 1 bytes
07-22 14:06:27.469: I/DeviceActivity(20370): Received: 234 message of 4 bytes
07-22 14:06:37.219: I/DeviceActivity(20370): Received: 1 message of 1 bytes
07-22 14:06:37.349: I/DeviceActivity(20370): Received: 234 message of 4 bytes
in Arduino i can write like this and i want something similar here:
//Get data from RS485:
void READ01(){
while (mySerial.available()){
mySerial.read();
}
mySerial.println("01READ");
momentas1="";
delay(20);
while (mySerial.available()) {
char c = mySerial.read();
if (c == '\n'){
break;
}
momentas1 += c;
}
}
This void READ01 adds chars to string until new line char comes.
You could use a buffer-like implementation by adding obtained string to another string until "\n" is received.
private String packet = "";
private void onBluetoothRead(byte[] buffer, int len) {
Log.i(LOGGER_TAG, String.format("Received: " + output.replace("\n", "") + " message of " + "%d bytes", len));
String output = new String(buffer, 0, len); // Add read buffer to new string
packet += output;
if (packet.endsWith( "\n" ) {
//do what you need to do
m_deviceOutput.append(output); // Add (not replace) string to TextView
StringTokenizer splitStr = new StringTokenizer(packet, ","); // split string by comma
String numberOne = splitStr.nextToken(); // First split string
String numberTwo = splitStr.nextToken(); // Second split string
numberOne = numberOne.replaceAll("\\D+",""); // replace all chars, leave only numbers
numberTwo = numberTwo.replaceAll("\\D+","");
packet = "";
}
}
I need to calculate the checksum of some strings that I need to send via bluetooth. There are 5 strings that I need to send, so, I need to create a function to calculate the checksum.
I need help creating the function to do this.
These are the strings:
/**String to calculate the Checksum*/
String message_part1 = send_command+" "+num_byte_trama1+" "+num_byte_variable+" "+pos_reg_1+" "+sendValue1;
String message_part2 = send_command+" "+num_byte_trama1+" "+num_byte_variable+" "+pos_reg_2+" "+sendValue2;
String message_part3 = send_command+" "+num_byte_trama1+" "+num_byte_variable+" "+pos_reg_3+" "+sendValue3;
String message_part4 = send_command+" "+num_byte_trama2+" "+num_byte_variable+" "+pos_reg_save_request;
String message_part5 = send_command+" "+num_byte_trama2+" "+num_byte_variable+" "+pos_reg_save_status;
/**Full message*/
String message_full1 = start_thread+" "+message_part1+" "+Checksum;
String message_full2 = start_thread+" "+message_part2+" "+Checksum;
String message_full3 = start_thread+" "+message_part3+" "+Checksum;
String message_full4 = start_thread+" "+message_part4+" "+Checksum;
String message_full5 = start_thread+" "+message_part5+" "+Checksum;
So, I need to create a function that reads a string, gets this string's bytes, calculates the Checksum, and then converts this value to hex.
This is what i've done. I don't know if it is correcto, and I still haven't done the int to hex conversion:
private String CalcChecksum (String message) {
byte[] byte_calc = message.getBytes();
int checksum = 0;
for (int byte_index = 0; byte_index < byte_calc.length; byte_index++) {
checksum += byte_calc[byte_index];
}
return checksum;
}
I used the .hashCode (String) method simply to create hashcode of an sms body+date, in order to avoid duplication during parsing sms.
This returns a 32 bit (signed) integer. For me this provides enough entropy to accept it as uniqId for a message, this is quite fast calculation and platform independent.
I have long string that at some part has
some text + "PHOTO;ENCODING=BASE64;TYPE=JPEG:" + some characters that generate randomly + /r/n...
I am wondering how can I delete part from
"PHOTO;ENCODING=BASE64;TYPE=JPEG:" untill /r/n
so I will be left only with
some text + /r/n ?
my code so far:
if (string.contains("PHOTO;ENCODING=BASE64;TYPE=JPEG:") {
string = string.replace("PHOTO;ENCODING=BASE64;TYPE=JPEG:", "");
}
but this obviously would not replace my random generated chars, only "PHOTO;ENCODING=BASE64;TYPE=JPEG:".
How do I "loop through" string from "PHOTO;ENCODING=BASE64;TYPE=JPEG:" untill /r/n ?
final String input = "some text + PHOTO;ENCODING=BASE64;TYPE=JPEG: + some characters that generate randomly + /r/n"
final int index = input.indexOf("PHOTO;ENCODING=BASE64;TYPE=JPEG:");
if (index != -1)
{
final String result = input.subString(0, index) + System.getProperty("line.separator")
}
why dont you try following
1) Get the index of "PHOTO;ENCODING=BASE64;TYPE=JPEG:". and call it idx
2)If idx != -1 then take substring of original string using str.subString(0,idx) and call it newStr
3)return newStr+(str.endsWith("\r\n")?"\r\n":"")