Recursive binary search program - recursion

Here's my method for a recursive binary search. This is suppose to find a phone number from a sorted list, but it's only working for the first number in the file and says everything else is not found. Can anyone help me figure out what's wrong?
static int binary (String num, String[] phone, int low, int high)
{
if ((high - low) <= 1)
{
if (phone [low].equals (num))
{
return low;
}
else if (phone [high].equals (num))
{
return high;
}
else
{
return -1;
}
}
int mid = (low + high) / 2;
if (phone [mid].compareTo (num) > 0)
{
return binary (num, phone, 0, mid);
}
else if (phone [mid].compareTo (num) < 0)
{
return binary (num, phone, mid, high);
}
else
{
return -1;
}
}

I think you want
if (phone [mid].compareTo (num) > 0)
{
return binary (num, phone, low, mid-1);
}
else if (phone [mid].compareTo (num) < 0)
{
return binary (num, phone, mid+1, high);
}
Also, you do more checks than are necessary:
static int binary (String num, String[] phone, int low, int high)
{
if(low > high)
{
return -1;
}
int mid = (low + high) / 2;
int compare = phone[mid].compareTo(num);
return compare > 0 ? binary (num, phone, low, mid-1);
: compare < 0 ? binary (num, phone, mid+1, high);
-1;
}

Related

Can anyone explain why my c++ code for arduino isnt working

I coded in C++ so that it takes input from the user and then lights up the corresponding LED
this is my code..
int rPin = 13;`
int gPin = 12;
int yPin = 11;
int dTime = 500;
String input;
//Strings
//String red = "red";
String prompt1 = "Enter the color : ";
String conformation = "Entered color is ";
void setup(){
pinMode(rPin,OUTPUT);
pinMode(gPin,OUTPUT);
pinMode(yPin,OUTPUT);
Serial.begin(9600);
}
void loop() {
Serial.println(prompt1);
input = Serial.readString();
while(Serial.available() == 0) {
}
if (input == "red"){
digitalWrite(rPin,HIGH);
delay(dTime);
digitalWrite(rPin,LOW);
delay(dTime);
} else if (input == "green"){
digitalWrite(gPin,HIGH);
delay(dTime);
digitalWrite(gPin,LOW);
delay(dTime);
} else if (input == "yellow"){
digitalWrite(yPin,HIGH);
delay(dTime);
digitalWrite(yPin,LOW);
delay(dTime);
}
// digitalWrite(gPin,HIGH);
// digitalWrite(yPin,HIGH);
There is no problem with my arduino circuit connection ,I triple checkeed it ...

Arduino code for multiple buttons and LED matrix

I'm trying to build a system using Arduino Uno, 8x8 LED matrix and 3 push buttons. The goal of the system is to display 3 different characters upon pushing the 3 buttons correspondingly. For instance, I've chosen the letters A,B,C. When the button corresponding to A is pressed, the letter A must be displayed and similar for B and C too. I'm kinda stuck in this code, where it seems logically correct for me but I have no idea why it isn't working. Thanks in advance.
#include "LedControlMS.h"
#define NBR_MTX 1
LedControl lc=LedControl(4,3,2, NBR_MTX);//
const int buttonPinA = 8;
const int buttonPinB = 9;
const int buttonPinC = 10;
char ip2;
void setup()
{
Serial.begin(9600);
for (int i=0; i< NBR_MTX; i++)
{
lc.shutdown(i,false);
lc.setIntensity(i,8);
lc.clearDisplay(i);
delay(100);
}
}
void Fun1()
{
lc.writeString(0,"A");
delay(500);
lc.clearAll();
}
void Fun2{
lc.writeString(0,"B");
delay(500);
lc.clearAll();
}
void Fun3()
{
lc.writeString(0,"C");
delay(500);
lc.clearAll();
}
void loop(){
if( digitalRead(buttonPinA) == HIGH){
ip2 = 1;}
else if(digitalRead(buttonPinB) == HIGH){
ip2 = 2;}
else if(digitalRead(buttonPinC) == HIGH){
ip2 = 3;
}
if(ip2 == '1'){
for(int i=1;i<=6;i++){
Fun1();
}
}
else if(ip2 == '2')
{
for(int i=1;i<=6;i++){
Fun2();}
}
else if(ip2 == '3'){
for(int i=1;i<=6;i++){
Fun3();}
}}
You're setting your char ip2 variable as an integer and then checking it as a character. You will see in this ASCII Table that '1' is equal to 31 as in integer, '2' is equal to 32 and so on.
Replacing the first few lines of you main loop with the code below should fix your problem. If not, I would check the documentation of the led library you're using and make sure you're implementing it correctly.
if( digitalRead(buttonPinA) == HIGH)
{
ip2 = '1';
}
else if(digitalRead(buttonPinB) == HIGH)
{
ip2 = '2';
}
else if(digitalRead(buttonPinC) == HIGH)
{
ip2 = '3';
}

Arduino global array not modified when accessed over serial?

I'm working on a home automation system, one part of which includes an Arduino Mega2560 connected via USB to a RaspberryPi 3 Model B. The Arduino receives two short, simple commands over serial from the Pi; the first command sets 'regions' of led lights, and the second sets colors on the regions previously described. Syntax is as follows for both commands, where bracketed items are single bytes, len+off are 3 ascii bytes interpreted as base-10, and r+g+b are 2 ascii bytes each interpreted as hex. The color set command supports a variable number of regions as shown:
Region Set Command
!c[regionId][stripId][len2][len1][len0][off2][off1][off0]\r
Color Set Command
!b[r1][r0][g1][g0][b1][b0][numRegions][regionId0]([regionId1]...)\r
Each command sends positive/negative acknowledgements so you'd think I'd be able to tell what's going wrong, but I get unexpected behavior when I try to set light colors with the second command, however, despite getting acknowledgements as expected. So far, the only reasonable conclusion I can come to is that for the global array regions discards changes and stays zero always. For example, this exchange results in no lights lit (comments are not in the actual exchange)
Pi sends: !c00144000\r // create regionId 0 on stripId 0; length 144 offset 0
Pi recieves: O // positive confirmation?
Pi sends: !b00009910\r // set regionId 0 to color 0x000099 (blue)
Pi recieves: O // positive confirmation, but no lights?
Pi sends: !x\r // invalid command; triggers default in switch
Pi recieves: X // as expected, all lights turn red
Here's the stripped down source for the Arduino:
#include "Arduino.h"
#include "FastLED.h"
#define WAIT while(!Serial.available()) ;;
// Forward Declarations
const int max_strips = 2;
const int max_strip_length = 300;
const int max_leds = max_strips * max_strip_length;
CRGB leds[max_strips][max_strip_length];
const int max_regions = 20;
int regions[max_regions][3];
const int baud_rate = 9600;
unsigned char buffer[64];
unsigned char currentByte = 0;
unsigned char incommingByte;
unsigned char startChar = '!';
unsigned char endChar = '\r';
bool store = false;
// Helper Functions
void set(CRGB c) {
for(int i = 0; i < max_strips; i++) {
for(int j = 0; j < max_strip_length; j++) {
leds[i][j] = c;
}
}
}
void set(int stripId, int length, int offset, CRGB c) {
for(int i = offset; i < offset+length; i++) {
leds[stripId][i] = c;
}
}
void setup() {
Serial.begin(baud_rate);
for(int i = 0; i < max_strips; i++) {
switch(i) {
case 0: {
FastLED.addLeds<WS2812B, 2, GRB>(leds[0], max_strip_length);
} break;
case 1: {
FastLED.addLeds<WS2812B, 3, GRB>(leds[1], max_strip_length);
} break;
}
}
set(CRGB::Black);
}
void loop() {
if(Serial.available() > 0) {
unsigned char incomingByte = Serial.read();
if(incomingByte == startChar) {
currentByte = 0;
store = true;
}
if(store) {
if(incomingByte == endChar) {
buffer[currentByte++] = incomingByte;
store = false;
switch(buffer[1]) {
case 'b': {
int red = (buffer[2] - '0')*16 + (buffer[3] - '0');
int green = (buffer[4] - '0')*16 + (buffer[5] - '0');
int blue = (buffer[6] - '0')*16 + (buffer[7] - '0');
int numRegions = buffer[8] - '0';
for(int i = 0; i < numRegions; i++) {
int regionId = buffer[9+i] - '0';
if(regionId >= max_regions) {
Serial.write('S');
return;
}
// Never sets anything
set(regions[regionId][0], regions[regionId][1], regions[regionId][2], CRGB(red, green, blue));
}
Serial.write('O');
} break;
case 'c': {
int regionId = buffer[2] - '0';
int stripId = buffer[3] - '0';
int length = (buffer[4] - '0')*100 + (buffer[5] - '0')*10 + (buffer[6] -'0');
int offset = (buffer[7] - '0')*100 + (buffer[8] - '0')*10 + (buffer[9] -'0');
if(regionId >= max_regions) {
Serial.write('R');
return;
}
if(stripId >= max_strips) {
Serial.write('S');
return;
}
regions[regionId][0] = stripId; // WE LOSE THESE VALUES??
regions[regionId][1] = length; // ??
regions[regionId][2] = offset; // ??
Serial.write('O');
} break;
default: {
set(CRGB::Red);
Serial.write('X');
} break;
}
currentByte = 0;
}else if(currentByte > 64){
store = false;
currentByte = 0;
} else {
buffer[currentByte++] = incomingByte;
}
}
}
FastLED.show();
}
I'd appreciate any advice as to what I'm missing here, and regardless, thanks for reading this far!
This was occurring because I have a lot of garbage showing up on the serial interface for the Arduino I'm testing on. Slowing the baud rate down to 2400bps resolves the issue on this device. Other Arduinos in the system do fine with much higher serial rates -- I suspect there's a hardware problem with the crystal on this particular Arduino so clock speeds aren't matching up correctly between the two sides of the serial connection.

Send stepper to position and back AccelStepper

At the moment I am working on a code that should send a plateau to a certain position and back. The plateau is being moved by the stepper. My goal is to press '4' on the keyboard and that then the steppers moves to a certain position. However, I am not succeding in this. I am using AccelStepper and at the moment I have the following code:
#include <AccelStepper.h>
AccelStepper stepper(1, 5, 4);
int spd = 1000; // The current speed in steps/second
int sign = 1; // Either 1, 0 or -1
int buttonState = 0;
void setup()
{
Serial.begin(9600);
stepper.setMaxSpeed(1000);
stepper.setSpeed(1000);
}
void loop()
{
char c;
if (Serial.available()) {
c = Serial.read();
if (c == 'f') { // forward
sign = 1;
}
if (c == 'r') { // reverse
sign = -1;
}
if (c == 's') { // stop
sign = 0;
}
if (c == '1') { // super slow
spd = 100;
}
if (c == '2') { // medium
spd = 900;
}
if (c == '3') { // fast
spd = 1000;
}
if (c == '4') {
//not working, does anyone know how to do this?
stepper.moveTo(500);
}
stepper.setSpeed(sign * spd);
}
stepper.runSpeed();
}
Does anyone have tips or know how to achieve this?
Thanks is advance!

Arduino making decision according to a packet received from serial port

The program listen to messages from serial port in the form or where first character (A or D) means analog or digital, the 2nd character - pin, the 3rd character - 1/0 or from 0 to 255. The markers < and > show the beginning and the end of packet.
For example, if packet is received, the light is turned on by digitalWrite(13,1)
But nothing happens. When I send via serial monitor, for instance: light is supposed to blink but it does not. The same with analogue outputs.
bool started = false;
bool ended = false;
char inData[5];
byte index;
void setup()
{
Serial.begin(9600);
}
void loop()
{
while (Serial.available() > 0)
{
char inChar = Serial.read();
if (inChar == '<')
{
index = 0;
started = true;
ended = false;
}
else if (inChar == '>')
{
ended = true;
break;
}
else
{
if (index <= 4)
{
inData[index] = inChar;
index++;
}
}
if (started && ended)
{
if (inData[0] == 'A')
{
pinMode(inData[2],OUTPUT);
analogWrite(inData[2],inData[4]);
}
else if (inData[0] == 'D')
{
if (inData[4] == 1)
{
pinMode(inData[2],OUTPUT);
digitalWrite(inData[2],HIGH);
}
else if (inData[4] == 0)
{
pinMode(inData[2],OUTPUT);
digitalWrite(inData[2],LOW);
}
}
started = false;
ended = false;
index = 0;
}
}
Serial.println("Sending");
}
The following code will allow you to execute a method with an example serial string:
<power,led>
Once it processes this string, it'll execute the following method:
sendCommand(cmd, val);
See below for an example of how to turn on an LED on PIN 11.
#include <avr/pgmspace.h>
int IRledPin = 11;
#define SOP '<'
#define EOP '>'
bool started = false;
bool ended = false;
char inData[80];
byte index;
void setup() {
pinMode(IRledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
// Read all serial data available, as fast as possible
while (Serial.available() > 0) {
char inChar = Serial.read();
if (inChar == SOP) {
index = 0;
inData[index] = '\0';
started = true;
ended = false;
} else if (inChar == EOP) {
ended = true;
break;
} else {
if (index < 79) {
inData[index] = inChar;
index++;
inData[index] = '\0';
}
}
}
// We are here either because all pending serial
// data has been read OR because an end of
// packet marker arrived. Which is it?
if (started && ended) {
// The end of packet marker arrived. Process the packet
char *cmd = strtok(inData, ",");
if (cmd) {
char *val = strtok(NULL, ",");
if (val) {
sendCommand(cmd, val);
}
}
// Reset for the next packet
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
}
void sendCommand(char *command, char *value) {
if (strcmp(command,"power") == 0) {
power(value);
}
}
void power(char* value) {
if (strcmp(value, "led") == 0) {
digitalWrite(IRledPin, HIGH);
}
}
If the 2nd character is the pin, then you want inData[1] for your pin numbers instead of inData[2].
Why do you go from inData[0] to inData[2]? Wouldn't the second character be in inData[1]?
You're setting the pinMode to the actual value of inData[2]. That means to turn on pin 13, you need to send a carriage return character ('\r').
The code doesn't run below but it should help you to sort out your problem.
What it tries to do is split the inData into the Tokens[] array.
It then turns the ASCII data into integers with the atoi() statement.
Hope it helps.
Got the splitter from Segmentation Fault when using strtok_r
bool started = false;
bool ended = false;
char inData[5];
byte index;
void setup()
{
Serial.begin(9600);
}
void loop()
{
while (Serial.available() > 0)
{
char inChar = Serial.read();
if (inChar == '<')
{
index = 0;
started = true;
ended = false;
}
else if (inChar == '>')
{
ended = true;
break;
}
else
{
inData[index] = inChar;
index++;
}
if (started && ended)
{
// https://stackoverflow.com/questions/2227198/segmentation-fault-when-using-strtok-r
// Splint up input data
char *p = inData;
char *tokens[50];
int i = 0;
while (i < 50) {
tokens[i] = strtok_r(p, ",", &p);
if (tokens[i] == NULL) {
break;
}
i++;
}
if (tokens[0] == '<A')
{
pinMode(tokens[1],OUTPUT);
analogWrite(tokens[2],tokens[3]);
}
else if (token[0] == '<D')
{
if (atoi(token[3]) == 1)
{
pinMode(atoi(token[1]),OUTPUT);
digitalWrite(atoi(token[1]),HIGH);
}
else if (atoi(tokens[3]) == 0)
{
pinMode(atoi(tokens[1]),OUTPUT);
digitalWrite(atoi(tokens[1]),LOW);
}
}
started = false;
ended = false;
index = 0;
}
}

Resources