Arduino Servo working in setup function but not with bluetooth command - java

i am experiencing a very strange issue, i wrote code for arduino UNO 3 which is designed to unlock door using servo motor, components attached are following
Servo Motor
1 Red Led (for failure alert)
1 Green Led (for success alert)
1 Buzzer (for audible alert on unlock)
The code is following
#include <Arduino_JSON.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <Servo.h>
String com = "";
const int buzzer = 6;
const int ledfalse = 8;
const int ledtrue = 13;
const int servo = 11;
Servo myservo;
SoftwareSerial mySerial(2, 3);
void ResetAdmin()
{
for (int i = 0 ; i < EEPROM.length() ; i++)
EEPROM.write(i, 0);
Blink(ledtrue, 2);
}
void WriteAdmin(String admin)
{
byte len = admin.length();
EEPROM.write(0, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(i + 1, admin[i]);
}
Blink(ledtrue, 2);
}
String ReadAdmin()
{
int newStrLen = EEPROM.read(0);
char data[newStrLen + 1];
for (int i = 0; i < newStrLen; i++)
{
data[i] = EEPROM.read(i + 1);
}
data[newStrLen] = '\0';
return String(data);
}
void Unlock()
{
Alert();
myservo.write(0);
delay(500);
myservo.write(90);
delay(6500);
myservo.write(360);
delay(500);
myservo.write(90);
}
void Blink(int type, int times)
{
for(int i = 1; i <= times; i++)
{
digitalWrite(type, HIGH);
delay(80);
digitalWrite(type, LOW);
delay(80);
}
}
void Alert()
{
for(int i = 1; i <= 4; i++)
{
tone(buzzer, 1000);
delay(80);
noTone(buzzer);
delay(80);
}
}
void ProcessCommand(String command)
{
if(command == "unlock")
Unlock(); //not works here
else if(command == "reset")
ResetAdmin();
else
{
Blink(ledfalse, 2);
}
}
void setup()
{
myservo.attach(servo);
mySerial.begin(9600);
pinMode(buzzer, OUTPUT);
pinMode(ledfalse, OUTPUT);
pinMode(ledtrue, OUTPUT);
//Unlock() or Blink(ledtrue, 4) or Alert() works here
digitalWrite(ledtrue, HIGH);
digitalWrite(ledfalse, HIGH);
delay(3000);
digitalWrite(ledtrue, LOW);
digitalWrite(ledfalse, LOW);
}
void loop()
{
while(mySerial.available() > 0)
{
delay(10);
com += (char)Serial.read();
}
if(com.length() > 0)
{
JSONVar doc = JSON.parse(com);
if (JSON.typeof(doc) != "undefined")
{
String admin = ReadAdmin();
if(admin == "")
{
admin = doc["admin"];
WriteAdmin(admin);
}
if(admin == doc["admin"])
{
ProcessCommand((const char*) doc["command"]);
}
else
{
Blink(ledfalse, 2);
}
}
else
{
Blink(ledfalse, 2);
}
com = "";
}
delay(10);
}
The java snippet for sending command is following
private void Unlock() {
if (btSocket != null) {
try {
String payload = "{\"admin\": \"" + getUUID() + "\", \"command\": \"unlock\"}";
btSocket.getOutputStream().write(payload.getBytes());
} catch (Exception e) {
e.printStackTrace();
biometricLoginButton.setImageResource(R.drawable.warning);
failed = true;
Toast.makeText(getBaseContext(), "Error occurred while unlocking", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getBaseContext(), "Door Lock not connected", Toast.LENGTH_SHORT).show();
biometricLoginButton.setImageResource(R.drawable.warning);
failed = true;
}
}
The issue is when i put the Alert(), Unlock() & Blink() function in the Arduino setup function then alert is working fine and so do the other two, but when the same functions called using Bluetooth signal none of them works. Note that the function is called as servo try to move but not correctly, this shows that Bluetooth is receiving data correctly from android and conditions are being evaluated correctly.

Finally i myself figured out the issue, basically the problem was with the EEPROM of the Arduino the problematic section of the code is following
String admin = ReadAdmin();
if(admin == "")
{
//on first run it never returned empty string, may be my reading function bug
admin = doc["admin"];
WriteAdmin(admin);
}
if(admin == doc["admin"])
{
//due to garbage value compared with actual one this block never executed
rocessCommand((const char*) doc["command"]);
}
else
{
Blink(ledfalse, 2);
}
First condition is for the first run so that when there is no admin stored in the EEPROM, then store the one coming in the JSON, but i don't know why but it was always some garbage value instead of empty or null string that's why the admin was not being matched e.g. the garbage value and the one received in JSON and thus not running the Unlock sequence

Related

Saving serial data in Processing

Hello all for the second time,
Initially I was looking for a broad answer, but this thread got blocked for being "too broad"... so I've got no choice, but to go into detail. My apologies if asking the question again is against the forum guidelines, I'm new to stackoverflow so please be kind.
I’ve got data coming into a serial port at 250Hz and I’d like to save it all to a .csv file. Of course draw() is not going to be able to keep up with that rate of data...
At the moment I am using the serialEvent(port) to collect and parse the data. Once parsed out, I'm calling a function in draw to add the data to a new line in a table and then saving that table every 5 seconds...
Yes, I see the obvious flaw that if I'm saving the current data in draw then of course it's not going to be able to save all the data coming in, but rather just the data that happens to be present when the data saving function is called... but I'm not sure of the best way to solve that. A buffer scheme? Or can I have a separate thread that just adds ALL data coming in to a table?
which lead to my initial (broad) question...
Is there a way to save all incoming data to a file without polling?
Thanks to all in advance.. code below:
Twain
import processing.serial.*;
import static javax.swing.JOptionPane.*;
Table table;
String Path = "PathProvidedHere.csv";
String message;
//Some time keeping variables
int hours, minutes, seconds, milliseconds;
float SaveTime;
//Serial port selection
Serial myPort;
String COMx, COMlist = "";
final boolean debug = true;
String portName;
// Data variables
float yaw = 0.0; float pitch = 0.0; float roll = 0.0;
float A1, A2, A3, A4;
float E1, E2, E3, E4;
void setup()
{
//Set up GIU box
size(1024, 768, P3D);
frameRate(250);
smooth();
//Some other setups like fonts, graphs, etc.
//Set up the logging table
table = new Table();
table.addColumn("A1"); table.addColumn("A2"); table.addColumn("A3"); table.addColumn("A4");
table.addColumn(""); table.addColumn("E1"); table.addColumn("E3"); table.addColumn("E4");
table.addColumn(" "); table.addColumn("min"); table.addColumn("sec"); table.addColumn("milli");
portName = chooseCOM();
delay(1000);
}
void draw()
{
SavetoCSV();
//serialEvent(myPort); // read and parse incoming serial message
ACouple();
Unrelated();
FunctionsHere();
if(millis() - SaveTime > 5000)
{
saveTable(table, Path);
SaveTime=millis();
}
}
String chooseCOM()
{
setupP2 = true;
try
{
if (debug) printArray(Serial.list());
int i = Serial.list().length;
if (i != 0)
{
if (i >= 2)
{
// need to check which port the inst uses -
// for now we'll just let the user decide
for (int j = 0; j < i; )
{
COMlist += char(j+'a') + " = " + Serial.list()[j];
if (++j < i) COMlist += ", ";
}
COMx = showInputDialog("Which COM port is correct? (a,b,..):\n"+COMlist);
if (COMx == null) exit();
if (COMx.isEmpty()) exit();
i = int(COMx.toLowerCase().charAt(0) - 'a') + 1;
}
String portName = Serial.list()[i-1];
if (debug) //println(portName + " Selected");
myPort = new Serial(this, portName, 115200); // change baud rate to your liking
myPort.bufferUntil(13); // buffer until CR/LF appears, but not required..
return portName;
}
else
{
showMessageDialog(frame, "Device is not connected to the PC");
exit();
}
}
catch (Exception e)
{ //Print the type of error
showMessageDialog(frame, "COM port is not available (may\nbe in use by another program)");
//println("Error:", e);
exit();
}
return "noPort";
}
void serialEvent(Serial myPort)
{
int newLine = 13; // new line character in ASCII
do
{
message = myPort.readStringUntil(newLine); // read from port until new line
if (message != null)
{
String[] list = split(trim(message), " ");
if (list.length == 4 && list[0].equals("i"))
{
yaw = float(list[1]); // convert to float yaw
pitch = float(list[2]); // convert to float pitch
roll = float(list[3]); // convert to float roll
}
else if (list.length == 5 && list[0].equals("s"))
{
A1 = float(list[1]);
A2 = float(list[2]);
A3 = float(list[3]);
A4 = float(list[4]);
}
else if (list.length >=2 && list[0].equals("b"))
{
Battery = int(list[1]);
}
else if (list.length >= 2 && list[0].equals("m"))
{
MACid = int(list[1]);
}
else
{
//print anything extra to console
//println(message);
}
}
} while (message != null);
}
void SavetoCSV()
{
if (A1 != 0)
{
TableRow newRow = table.addRow();
newRow.setFloat("A1", (A1));
newRow.setFloat("A2", (A2));
newRow.setFloat("A3", (A3));
newRow.setFloat("A4", (A4));
//saveTable(table, Path);
}
}
Additional info:
- Processing P3
- For the record, with the rest of my script I can get draw up to 80hz or so
- I'd be okay with saving all the data and parsing it later
Went the buffer route.... I think I'm getting close now. Unsure if I'm saving the data in the right order or if the saving process will halt the rest of the processes...
Code:
import processing.serial.*;
import static javax.swing.JOptionPane.*;
//Arrays to save the data
LinkedList<Integer> A1c = new LinkedList<Integer>();
LinkedList<Integer> A2c = new LinkedList<Integer>();
LinkedList<Integer> A3c = new LinkedList<Integer>();
LinkedList<Integer> A4c = new LinkedList<Integer>();
int bufferLength = 500;
int bufflen = 0;
//Serial port selection
Serial myPort;
String COMx, COMlist = "";
final boolean debug = true;
String portName;
// Data variables
float yaw = 0.0; float pitch = 0.0; float roll = 0.0;
float A1, A2, A3, A4;
//Data log variables
Table table;
String Path = "PathtoFile.csv";
void setup() {
//Set up GIU box
size(1024, 768, P3D);
frameRate(250);
strokeWeight(50);
smooth();
//Set up the logging table
table = new Table();
table.addColumn("A1"); table.addColumn("A2"); table.addColumn("A3"); table.addColumn("A4");
portName = chooseCOM();
}
void draw() {
//SavetoCSV now called within SerialEvent()
//SavetoCSV();
//serialEvent(myPort); // read and parse incoming serial message
Some();
Unrelated();
FunctionsHere();
}
void serialEvent(Serial myPort) {
int newLine = 13; // new line character in ASCII
do {
message = myPort.readStringUntil(newLine); // read from port until new line
if (message != null) {
String[] list = split(trim(message), " ");
if (list.length == 4 && list[0].equals("i")) {
yaw = float(list[1]); // convert to float yaw
pitch = float(list[2]); // convert to float pitch
roll = float(list[3]); // convert to float roll
} else if (list.length == 5 && list[0].equals("s")) {
A1 = float(list[1]);
A2 = float(list[2]);
A3 = float(list[3]);
A4 = float(list[4]);
if (bufflen < bufferLength) {
A1c.push(int(A1));
A2c.push(int(A2));
A3c.push(int(A3));
A4c.push(int(A4));
bufflen++;
}
else{
bufflen = 0;
SavetoCSV();
}
} else if (list.length >=2 && list[0].equals("b")) {
Battery = int(list[1]);
} else if (list.length >= 2 && list[0].equals("m")) {
MACid = int(list[1]);
} else {
//print anything extra to console
//println(message);
}
}
} while (message != null);
}
void SavetoCSV() {
if (A1 != 0) {
for (int i = bufferLength - 1; i >= 0; i--){
if (i < bufferLength){
TableRow newRow = table.addRow();
newRow.setFloat("A1", (A1c.get(i)));
newRow.setFloat("A2", (A2c.get(i)));
newRow.setFloat("A3", (A3c.get(i)));
newRow.setFloat("A4", (A4c.get(i)));
} else saveTable(table, Path);
}
}
}
String chooseCOM() {
setupP2 = true;
try {
if (debug) printArray(Serial.list());
int i = Serial.list().length;
if (i != 0) {
if (i >= 2) {
// need to check which port the inst uses -
// for now we'll just let the user decide
for (int j = 0; j < i; ) {
COMlist += char(j+'a') + " = " + Serial.list()[j];
if (++j < i) COMlist += ", ";
}
COMx = showInputDialog("Which COM port is correct? (a,b,..):\n"+COMlist);
if (COMx == null) exit();
if (COMx.isEmpty()) exit();
i = int(COMx.toLowerCase().charAt(0) - 'a') + 1;
}
String portName = Serial.list()[i-1];
if (debug) //println(portName + " Selected");
myPort = new Serial(this, portName, 115200); // change baud rate to your liking
myPort.bufferUntil(13); // buffer until CR/LF appears, but not required..
return portName;
} else {
showMessageDialog(frame, "Device is not connected to the PC");
exit();
}
}
catch (Exception e)
{ //Print the type of error
showMessageDialog(frame, "COM port is not available (may\nbe in use by another program)");
//println("Error:", e);
exit();
}
return "noPort";
}

Program freezes when trying to analyse a string

I am writing on a method which should analyse a polynomial given by the user (as String) and do different stuff with it in the future. At the moment, I was trying to test the code I have so far but whenever I execute the program, it freezes and after sitting for hours in front of the computer I still can't find the culprit in it.
I was testing if a polynomial of one variable could be analysed and then re-printed, but it doesn't work.
I hoped anyone could help me out on this.
Here's the code block in the main which executes the method, the string userInput is a polynomial (e.g 4x-6x^2):
String userInput = inputArea.getText().trim();
Monomials monomials = new Monomials();
monomials.analyse(userInput);
Here's the class monomials with its method analyse():
//Class Monomial
class Monomials
{
private int coeff = 0;
private char var;
private int addpow = 1;
private int pow;
private char powsign = '^';
private char minus = '-';
private boolean isnegative = false;
private String mono;
StringBuilder stringBuilder = new StringBuilder();
public int getCoeff(int coeff)
{
return coeff;
}
public void setCoeff(int coeff)
{
this.coeff = coeff;
}
public void setVar(char var)
{
this.var = var;
}
public void setPow(int pow)
{
this.pow = pow;
}
public String getMono(String monomials)
{
return mono;
}
// Method to further analyse user's input.
public void analyse(String polynomial)
{
//Split the poynomial into monomials and store them in an array list.
polynomial = polynomial.replaceAll("-","+-");
String polyParts[] = polynomial.split("\\+");
ArrayList<String> monomials = new ArrayList<String>(Arrays.asList(polyParts));
// Iterate the monomials.
for (int i = 0; i <= monomials.size(); i++)
{
String monomial = monomials.get(i);
// Analyse the monomial.
for (int x = 0; x <= monomial.length(); x++)
{
char c = monomial.charAt(x);
int countcoeff = 0;
int countvar = 0;
// check if negative.
if (c == minus)
{
isnegative = true;
x++;
}
// get the coefficient.
if (Character.isDigit(c))
{
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
if (isnegative)
{
setCoeff(Integer.parseInt(monomial.substring(1, countcoeff)));
} else
{
setCoeff(Integer.parseInt(monomial.substring(0, countcoeff)));
}
}
// get the variable.
if (Character.isLetter(c))
{
char var = c;
while (Character.isLetter(var))
{
countvar++;
addpow++;
x++;
}
}
// get the power.
if (c == powsign)
{
countvar++;
x++;
while (Character.isDigit(c))
{
x++;
}
if (isnegative)
{
setPow(Integer.parseInt(monomial.substring(countcoeff+countvar+2, x)));
} else
{
setPow(Integer.parseInt(monomial.substring(countcoeff+countvar+1, x)));
}
pow += addpow;
}
}
if (isnegative)
{
stringBuilder.append(String.valueOf(minus));
}
stringBuilder.append(String.valueOf(coeff) + String.valueOf(var) + String.valueOf(powsign) + String.valueOf(pow));
mono = stringBuilder.toString();
monomials.set(i, mono);
}
for (int i = 0; i < monomials.size(); i++)
{
System.out.println(String.valueOf(monomials.get(i)));
}
} // End of method analyse().
} // End of class Monomial
You have a couple of loops which will never exit:
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
How to find out Stuff like that?
If you use Eclipse, you can run your Code in Debug Mode, switch to the debug-perspective and click on the yellow Suspend-Symbol. That will suspend your Program, in the Debug-View you can see in which line the Thread is "hanging", if you click on it it will open the source-code.
If you don't use an IDE with that function, you can use the JDK-Tools: Use jps to find out the ID of your program:
C:\jdk\jdk8u45x64\jdk1.8.0_45\bin>jps
7216
5688 Jps
6248 Monomials
Then use jstack to print a stack trace of all running threads:
C:\jdk\jdk8u45x64\jdk1.8.0_45\bin>jstack 6248
[other threads omitted]
"main" #1 prio=5 os_prio=0 tid=0x000000000203e800 nid=0x1b2c runnable [0x000000000201e000]
java.lang.Thread.State: RUNNABLE
at Monomials.analyse(Monomials.java:77)
at Monomials.main(Monomials.java:10)
one of your loop is running infinitely. You should replace it with if condition.
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
replace it with
if (Character.isDigit(c))
{
countcoeff++;
x++;
}
Or you could use break statement here.
As the others stated already
while (Character.isDigit(c))
is your problem.
But you have that two times not one time, so both are a problem. The 2nd isn't a real problem, because Character.isDigit and if (c == powsign) can´t be both true at the same time, so the 2nd inifit loop never gets executed, which brings me to the next point: bugs.
In your code there are a tremendous amount of them :-D
Both for loops are running to far (<= .size() & <= .length()), replace <= with <.
Also, the x++ placed around in your code are wrong. x gets incremented automaticially and if you want to exit the loop early, use break; or use continue; if you want to jump to the next iteration early.

Raspberry PI + Wiegand RFID

I have problem with my Wiegand RFID reader (26bit). I have write simple Java app and everything seems fine. But after 10 reads for example, it starts to shift bits. Is RPi Raspbian to slow for Wiegand time protocol?
Here is sample code and output
package classes;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.RaspiPin;
public class Test {
public static char[] s = new char[10000];
static int bits = 0;
public static void main(String[] args) {
// create gpio controller
final GpioController gpio = GpioFactory.getInstance();
// provision gpio pin #02 as an input pin with its internal pull down
// resistor enabled
final GpioPinDigitalInput pin0 = gpio.provisionDigitalInputPin(RaspiPin.GPIO_00, PinPullResistance.PULL_UP);
final GpioPinDigitalInput pin1 = gpio.provisionDigitalInputPin(RaspiPin.GPIO_01, PinPullResistance.PULL_UP);
System.out.println("PINs ready");
Thread th = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
if (pin0.isLow()) { // D1 on ground?
s[bits++] = '0';
while (pin0.isLow()) {
}
}
if (pin1.isLow()) { // D1 on ground?
s[bits++] = '1';
while (pin1.isLow()) {
}
}
if (bits == 26) {
bits=0;
Print();
}
}
}
});
th.setPriority(Thread.MAX_PRIORITY);
th.start();
System.out.println("Thread start");
for (;;) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
protected static void Print() {
for (int i = 0; i < 26; i++) {
System.out.write(s[i]);
}
System.out.println();
bits = 0;
}
}
and output:
10100100111111110110011011
10100100111111110110011011
10100100111111110110011011
10100100111111110110011011
10100100111111110001101110
10010011111111011001101110
10010011111111011001101110
10010011111111011001101110
10010011111111011001101110
10010011111111011001101110
10010011111111011001101110
Your printf statements may be causing the problem. Try storing the data and printing it at the end. printf tends to be slow (it involves several context switches).
Also, it seems you have no way of detecting if you miss a bit. I would say try a timeout, so if you don't get 26 bits in time reset your counter. That way you're not looping around reading nothing, and eventually getting misaligned data.
I have done this in C and python on a pi and also on an arduino. From my experience as #woodrow douglas says you need to capture the bits in a loop or use interrupts (better) and use a timeout which you increase each time you receive a bit and then print it out once you are sure you have all the bits (timed out).
This is how I do this on arduino using interrupts.
void zero(){
bit_count ++;
bit_holder = (bit_holder << 1) + 0; //shift left one and add a 0
timeout = t;
}
void one(){
bit_count ++;
bit_holder = (bit_holder << 1) + 1; //shift left one and add a 1
timeout = t;
}
void loop() {
timeout --;
if (timeout == 0 && bit_count > 0){
lcd.clear();
lcd.print("Dec:");
lcd.print(bit_holder);
lcd.setCursor(0,1);
lcd.print("Hex:");
lcd.print(String(bit_holder,HEX));
Serial.print("bit count= ");
Serial.println(bit_count);
Serial.print("bits= ");
Serial.println(bit_holder,BIN);
oldbit = bit_holder; //store previous this value as previous
bit_count = 0; //reset bit count
bit_holder = 0; //reset badge number
}
}
I never got any issues using C on Pi but I did get issues using python as it is not as real time. The only way it would work in Python was by using interrupts and I managed too get the bad read rate down to something like 1 in 200 but never completely remove it.
What I did in the end was use some C to collect the bits then call my python script with the bits for processing.
If you are interested this is the C code I use:
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
int r1data0 = 6; //pin 22
int r1data1 = 7; // Pin 7
// green goes to same as relay
int r1beep = 0; //pin 11
int r2data0 = 10; /* P1-24 */
int r2data1 = 11; /* P1-26 */
//green goes to same as relay
int r2beep = 0;
int i1 = 0;
int i2 = 0;
//generic variables
int t = 5;
int blank; //blank variable to reset bits
int rel1time = 0;
int rel2time = 0;
int rel1 = 5;
int previoust;
//reader 1variables
int r1bits; // Collected bits storage area
int r1bit_count = 0; //to measure the size of bits
int oldr1bit_count = 0; //somewhere to store bitcount to send to python
int r1timeout; //timout to return correct value
char r1command[40];
int r1ret;
//reader 2 variables
int r2bits; // Collected bits storage area
int r2bit_count = 0; //to measure the size of bits
int oldr2bit_count = 0;
int r2timeout; //timout to return correct value
char r2command[40];
pthread_t threads;
void access_denied(int red){
int pin;
if(red = 1){pin = r1beep;}
if(red = 2){pin = r2beep;}
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delay(300);;
digitalWrite(pin, HIGH);
delay(200);
digitalWrite(pin, LOW);
delay(300);
digitalWrite(pin, HIGH);
delay(200);
digitalWrite(pin, LOW);
delay(300);
digitalWrite(pin, HIGH);
}
void *r1python_thread(void *val){
sprintf(r1command,"python access.py r1 %X %X", oldr1bit_count, val); //build python command
FILE* file = popen(r1command, "r"); //execute command using popen
char buffer[5];
fscanf(file, "%100s", buffer); //read command output
pclose(file);
//printf("buffer is : %s\n", buffer);
rel1time = atoi(buffer); //convert returned string to int
if(rel1time == 0){access_denied(1);}
pthread_exit(NULL);
}
void *r2python_thread(void *val){
sprintf(r2command,"python access.py r2 %X",val); //build python command
FILE* file = popen(r2command, "r"); //execute command using popen
char buffer[5];
fscanf(file, "%100s", buffer); //read command output
pclose(file);
//printf("buffer is : %s\n", buffer);
rel2time = atoi(buffer); //convert returned string to int
pthread_exit(NULL);
}
//reader 1 bit functions
void onebit0(){ //adds a 0
r1bit_count ++; //increase bit count
r1bits = (r1bits << 1) + 0;
r1timeout = t; //reset timeout
}
void onebit1(){ //adds a 1
r1bit_count ++;
r1bits = (r1bits << 1) + 1;
r1timeout = t;
}
//reader 2 bit functions
void twobit0(){ //adds a 0
r2bit_count ++; //increase bit count
r2bits = (r2bits << 1) + 0;
r2timeout = t; //reset timeout
}
void twobit1(){ //adds a 1
r2bit_count ++;
r2bits = (r2bits << 1) + 1;
r2timeout = t;
}
int main(){
wiringPiSetup(); //initialise wiringPi
pinMode (r1data0, INPUT); // set reader 1 data0 as input
pinMode (r1data1, INPUT); // set reader 1 data1 as input
pinMode (r2data0, INPUT); // set reader 2 data0 as input
pinMode (r2data1, INPUT); // set reader 2 data1 as input
//reader 1
wiringPiISR(r1data0, INT_EDGE_FALLING, onebit0); // set interrupt on data 0 if it falls call bit0 function
wiringPiISR(r1data1, INT_EDGE_FALLING, onebit1); // set interrupt on data 1 if it falls call bit1 function
//reader 2
wiringPiISR(r2data0, INT_EDGE_FALLING, twobit0); // set interrupt on data 0 if it falls call bit0 function
wiringPiISR(r2data1, INT_EDGE_FALLING, twobit1); // set interrupt on data 1 if it falls call bit1 function
while (1){ //loop
if (r1bit_count > 0 ){ //if bits is not empty
r1timeout--; // reduce timeout by 1
if(r1timeout == 0){ //and it has timed out ie no more bits coming
//printf("%X\n",r1bits);
pthread_create(&threads, NULL, r1python_thread,(void *) r1bits); //start new thread for python program
oldr1bit_count = r1bit_count;
r1bit_count = 0; //reset bit count
r1bits = blank; //clear bits cariable
r1timeout = t; //reset timeout
}
}
if (r2bit_count > 0 ){ //if bits is not empty
r2timeout--; // reduce timeout by 1
if(r2timeout == 0){ //and it has timed out ie no more bits coming
pthread_create(&threads, NULL, r2python_thread,(void *) r2bits); //start new thread for python program
r2bit_count = 0; //reset bit count
r2bits = blank; //clear bits cariable
r2timeout = t; //reset timeout
}
}
if (rel1time > 0){
pinMode(rel1, OUTPUT);
int diff = time(NULL) - previoust;
if(diff >= 1){
previoust = time(NULL);
rel1time--;
}
}
else{
pinMode(rel1, INPUT);
previoust = time(NULL);
}
delay(1);
}
return 0;
}

How to call this method from library?

I am not sure how to call this method from another class, deleteSurroundingText(int leftLength, int rightLength) It is in Class EmulatorView in a library. But it also seems nested in some other classes, so I can't say something like EmulatorView.deleteSurroundingText(1,1);
Here is what it says about the method:
boolean jackpal.androidterm.emulatorview.EmulatorView.onCreateInputConnection(...).new BaseInputConnection() {...}.deleteSurroundingText(int leftLength, int rightLength)
boolean jackpal.androidterm.emulatorview.EmulatorView.onCreateInputConnection(...).new BaseInputConnection() {...}.deleteSurroundingText(int leftLength, int rightLength)
Overrides: deleteSurroundingText(...) in BaseInputConnection
public boolean deleteSurroundingText (int beforeLength, int afterLength)
Added in API level 3
The default implementation performs the deletion around the current selection position of the editable text.
Parameters
beforeLength The number of characters to be deleted before the current cursor position.
afterLength The number of characters to be deleted after the current cursor position.
Section of code:
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.inputType = mUseCookedIme ?
EditorInfo.TYPE_CLASS_TEXT :
EditorInfo.TYPE_NULL;
return new BaseInputConnection(this, true) {
public boolean deleteSurroundingText(int leftLength, int rightLength) {
Log.w(TAG2, "in DeleteSurroundingText");
if (LOG_IME) {
Log.w(TAG, "deleteSurroundingText(" + leftLength +
"," + rightLength + ")");
}
if (leftLength > 0) {
for (int i = 0; i < leftLength; i++) {
sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
}
} else if ((leftLength == 0) && (rightLength == 0)) {
// Delete key held down / repeating
sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
}
// TODO: handle forward deletes.
//int i = 1;
//deleteSurroundingText(i, i);
return true;
}
};
}
Thanks

junit arrays not equal test

I'm trying to write a test case where my scenario is that two byte arrays should be not equal.
Can I do this with junit?
Or do I have to use something external like Hamcrest? I couldn't change the code in this answer to do the job
Please give a sample.
You can use
assertFalse(Arrays.equals(array1, array2));
If you wanted to check they were equal, I would use the following instead.
assertEquals(Arrays.toString(array1), Arrays.toString(array2));
as this produces a readable output as to what was different rather than just failing.
I prefer doing this the Hamcrest way, which is more expressive:
Assert.assertThat(array1, IsNot.not(IsEqual.equalTo(array2)));
Or the short version with static imports:
assertThat(array1, not(equalTo(array2)));
(The IsEqual matcher is smart enough to understand arrays, fortunately.)
Note that a limited version of Hamcrest is part of the JUnit 4.x distribution, so you don't need to add an external library.
Newer versions of JUnit offer org.junit.Assert.assertArrayEquals(byte[], byte[]), with overloads for other array types. Failures show the first index with a non-match and the differing elements at that index.
I also enjoy assertEquals(Arrays.asList(expected), Arrays.asList(actual)). The Hamcrest-powered rendition mentioned above is probably best.
Here is a possible alternative, which has the advantage of using the same code as assertArrayEquals() :
private void assertArrayNotEquals(byte[] expecteds, byte[] actuals) {
try {
assertArrayEquals(expecteds, actuals);
} catch (AssertionError e) {
return;
}
fail("The arrays are equal");
}
You could do it like this:
assertNotEquals(arrayOne, arrayTwo)
Sorry this is a bit long but it's easy to debug with and you can cut and paste it into your unit test.
private int span = 10;
private boolean equal(byte[] expected, byte[] got) {
final boolean result;
String message = null;
int offset = -1;
int length = -1;
if(expected == null && got == null) {
result = true;
} else if(expected == null || got == null) {
message = "One array is null: " + (expected == null ? "expected" : "got");
result = false;
} else if(expected.length != got.length) {
message = "Lengths differ: expected = " + expected.length + ", got = " + got.length;
result = false;
} else {
length = expected.length;
for(int i = 0; i < length; i++) {
if(expected[i] != got[i]) {
offset = i;
break;
}
}
result = offset == -1;
if(!result) {
message = "Contents differ";
}
}
if(!result) {
System.err.println(message);
if(offset >= 0) {
hexDump("Expected: ", expected, offset, length);
hexDump(" Got: ", got, offset, length);
}
}
return result;
}
private void hexDump(String label, byte[] ba, int offset, int length) {
System.err.print(label);
if(ba == null) {
System.err.println("<null>");
} else if(ba.length == 0) {
System.err.println("<zero-length-array>");
} else {
// <span> bytes either side
final int from = Math.max(0, offset - span);
final int to = Math.min(length, offset + span);
if(from != 0) {
System.err.print("(offset:" + from + ") ");
}
for(int i = from; i < to; i++) {
System.err.printf("%02X ", new Byte(ba[i]));
}
System.err.println();
}
}
#Test
public void testExample() {
assertTrue(equal(new byte[] { 1, 2, 3 }, new byte[] { 1, 8, 3 }));
}

Categories

Resources