Help with MIT App Inventor

The sensors on my UNO are sending ff and fe, each has its respective equivalent binary value of 11111110 and 11111111. I want to just obtain the last number (bit 7) so it can be sent back to my UNO. Right now the current block section that does this is in [1.png]. Can someone help with the logic? I've thought about using a mask but do not know how to use that here.

how to attach an image

Here's OP's pic:

Wouldn't it be better to ask how to create MIT App Inventor stuff on an MIT App Inventor forum? Is there one?

The fact that that app sends to and / or receives from an Arduino doesn't really make it an Arduino problem. (Although I suppose there will be Arduinites who know MIT App Inventor and will help if they can? I looked into it once and it made my eyes bleed.)

oremlaa:
Can someone help with the logic? I've thought about using a mask but do not know how to use that here.

Just subtract 0xFE from the value.

...R

oremlaa:
I've thought about using a mask but do not know how to use that here.

Very likely AI doesn't have that function. It's way too advanced for the target audience.

I've recently built a quite complex app with it, but in the future will definitely rewrite in Android Studio as the limitations of AI are just so horrible...

I've never had the need to do bit manipulation in AI, but glancing at the documentation, there doesn't seem to be a way to do bit comparisons directly.

If you're certain the upper 7 bits are always set, Robin's suggestion should work. If they are unknown, Modulo(x,2) should give the value of the least significant bit. With appropriate use of "divide", "round", "modulo", one could check arbitrary bits. A third rather roundabout approach would be to use "format as decimal" to get a string representation, "convert number" to get a binary string representation, and index into this string to get bit values.

To wvmarle's comment App Inventor is great for doing simple data transfers on supported interfaces and at creating simple text user interfaces, things that are common in the Arduino world. When it comes to doing significant data manipulation and larger projects it gets unwieldy pretty quickly and one might consider moving to Android Studio. The flip side is that the learning curve for Android Studio is orders of magnitude more difficult than App Inventor.

Of course another option is to send the 0xFE or 0xFF to the Arduino and apply a mask in the Arduino code.

...R

I think that the characters in a text string in App inventor are numbered from left to right starting with 1.

I'm not certain what you two things you are joining together, but in the segment block, try changing the start from 1 to 7, and make the length 1. Does this append only the last 0 or 1?

Just out of curiosity I have had a closer look at the AI code in Reply #1 - it is even more cryptic than C++. I thought it was intended to be easy :slight_smile:

...R

Robin2:
Of course another option is to send the 0xFE or 0xFF to the Arduino and apply a mask in the Arduino code.

Or, since:

oremlaa:
The sensors on my UNO are sending ff and fe,

.... why not just fix them in the Uno to start with? Why do the FE and FF even need to leave the boundaries of the Uno?

Or does "sensors on my uno" not mean sensors being read by and into the Uno? Are the sensors themselves doing the sending to AI, in which case what does "sensors on my uno" mean?

Maybe a diagram would help?

sayHovis:
Or, since:

.... why not just fix them in the Uno to start with?

DOH! - Senior moment (again)

...R

Robin2:
DOH! - Senior moment (again)

...R

Well it's a leap of faith to say the numbers actually start in the Uno: it's not 100% clear (to me, any road) how this whole palaver is hooked up.

This is how it's currently wired (: thanks for the help everyone I'm trying out your suggestions right now. Will update you guys on the results

Image from Reply #11 so we don't have to download it. See this Simple Image Guide

And smaller image files (640 x 480 should be fine) are kinder to those of us with slow or expensive internet connections.

...R

oremlaa:
I'm trying out your suggestions right now.

You mean to try fix it in the Arduino if that's where it starts out once the sensor produces the value, rather than send it to AI to fix it and send it back to where it started?

I've also attached the arduino code here, if that helps.

scoreboard_edit_ino.ino (7.07 KB)

I'd be keen to hear, without having to wade through code, if the "faulty" versions of the sensor values FE and FF exist as FE and FF inside the Arduino before you send them to AI for "fixing". Since if they do, it seems you can "fix" them there and then....

Can you explain more about the architecture, and what is the role of the Android app. I don't see any Serial.read() for data back from Android to Arduino.
Is the AP inventor issue with the output from setShot(int mode)?

//----------------------------------------------------------------------------//
// Filename    : Scoreboard.ino                                               //
// Description : Smart Basketball Scoreboard                                  //
// Version     : 1.1.0                                                        //
//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//
// DEFINITIONS                                                                //
//----------------------------------------------------------------------------//

// TURN ON DEBUG MODE
//#define DEBUG
//#define DEBUG_PROX
//#define DEBUG_VIBR

//----------------------------------------------------------------------------//
// CONSTANTS                                                                  //
//----------------------------------------------------------------------------//

// PINS
const int prox_pin = 2;
const int vibr_pin = 3;
const int led_r_pin = 8;
const int led_g_pin = 9;
const int led_b_pin = 10;

// TIME
const unsigned long wait_interval = 3000;

// MATH
const float percent_to_bright_factor = 100 * log10(2) / log10(255);

//----------------------------------------------------------------------------//
// VARIABLES                                                                  //
//----------------------------------------------------------------------------//

// TIME
unsigned long wait_time;

// STATUS
boolean prox = false;
boolean vibr = false;
boolean wait = false;

//----------------------------------------------------------------------------//
// FUNCTIONS (SETTINGS)                                                       //
//----------------------------------------------------------------------------//

void setup() {
  // INITIATE PINS
  pinMode(prox_pin, INPUT);
  pinMode(vibr_pin, INPUT);
  pinMode(led_r_pin, OUTPUT);
  pinMode(led_g_pin, OUTPUT);
  pinMode(led_b_pin, OUTPUT);

  set_led(5, 100);

  // INITIATE SERIAL COMMUNICATION
  Serial.begin(9600);

  // INITIATE BLUETOOTH COMMUNICATION
  setup_bluetooth();

  set_led(4, 100);

#ifdef DEBUG
  Serial.println("Board is alive");
  Serial.println();
#endif
}

void setup_bluetooth() {
#ifdef DEBUG
  Serial.println("Setting Bluetooth");
  Serial.println();
#endif

  Serial.begin(38400);                   // Set baud rate
  Serial.print("\r\n+STWMOD=0\r\n");     // Set to work in slave mode
  Serial.print("\r\n+STNA=Arduino\r\n"); // Set name
  Serial.print("\r\n+STOAUT=1\r\n");     // Permit Paired device to connect me
  Serial.print("\r\n+STAUTO=0\r\n");     // Auto-connection should be forbidden here
  delay(2000);                            // This delay is required.
  Serial.print("\r\n+INQ=1\r\n");        // Make the slave inquirable
  delay(2000);                            // This delay is required.
  while (Serial.available()) {           // Clear data
    delay(50);
    Serial.read();
  }
}

//----------------------------------------------------------------------------//
// FUNCTIONS (LIGHT)                                                          //
//----------------------------------------------------------------------------//

int percent_to_bright(int percent) {
  // PERCENT:
  // 0..100
  // RETURN BRIGHT
  // 255..0

  return 256 - pow(2, percent / percent_to_bright_factor);
}

void set_led(int color, int bright) {

#ifdef DEBUG
  Serial.println("Board is alive");
  Serial.println();
#endif

  if (color < 0 || color > 6 || bright < 0 || bright > 100) {
    return;
  }

  int led_r_bright = 255;
  int led_g_bright = 255;
  int led_b_bright = 255;
  int bright_aux = percent_to_bright(bright);

  switch (color) {
    case 0:
      // Green //PROXIMITY // Make
      led_r_bright = 0;
      led_g_bright = 255;
      led_b_bright = 0;
      break;
    case 1:
      // YELLOW //VIBRATE
      led_r_bright = 255;
      led_g_bright = 255;
      led_b_bright = 0;
      break;
    case 2:
      // OFF //laggy vibrate
      led_r_bright = 0;
      led_g_bright = 0;
      led_b_bright = 0;
      break;
    case 3:
      // CYAN
      led_r_bright = 0;
      led_g_bright = 255;
      led_b_bright = 255;
      break;
    case 4:
      // BLUE //IDLE
      led_r_bright = 0;
      led_g_bright = 0;
      led_b_bright = 255;
      break;
    case 5:
      // MAGENTA
      led_r_bright = 255;
      led_g_bright = 0;
      led_b_bright = 255;
      break;
    case 6:
      // WHITE
      led_r_bright = 255;
      led_g_bright = 255;
      led_b_bright = 255;
      break;
  }

  analogWrite(led_r_pin, led_r_bright);
  analogWrite(led_g_pin, led_g_bright);
  analogWrite(led_b_pin, led_b_bright);

  return;
}

//----------------------------------------------------------------------------//
// FUNCTIONS (CHECK)                                                          //
//----------------------------------------------------------------------------//

void check_prox() {
  if (!prox) {
    if (digitalRead(prox_pin) == LOW) {
#ifdef DEBUG_PROX
      Serial.println("Proximity detected");
      Serial.println();
#endif

      prox = true;
      if (!vibr) {
        wait = true;
        wait_time = millis() + wait_interval;
      }
      set_shot(1);
    }
  }
}

void check_vibr() {
  if (!prox && !vibr) {
    if (digitalRead(vibr_pin) == HIGH) {
#ifdef DEBUG_VIBR
      Serial.println("Vibration detected");
      Serial.println();
#endif
      vibr = true;
      wait = true;
      wait_time = millis() + wait_interval;
      set_led(1, 100);
    }
  }
}

void check_wait() {
  if (wait && millis() > wait_time) {
    if (!prox) {
      set_shot(0);
    }

    reset();
  }
}

//----------------------------------------------------------------------------//
// FUNCTIONS (MIS)                                                            //
//----------------------------------------------------------------------------//

void set_shot(int mode) {
  // MODE:
  // 0 = WRONG SHOT (MISS)
  // 1 = RIGHT SHOT (SCORE)

  if (mode == 0) {
    set_led(2, 100); // sets the colour of the "lag" after miss
  } else {
    set_led(0, 100);
  }
  Serial.print(mode);
  delay(1000);
}

void reset() {
  vibr = false;
  prox = false;
  wait = false;
  set_led(4, 100);
}

//----------------------------------------------------------------------------//
// MAIN                                                                       //
//----------------------------------------------------------------------------//

void loop() {
  check_prox();
  check_vibr();
  check_wait();
}

So the Arduino App is mostly for determining whether the shot was made or not. The sensors are hooked on to the UNO and it's supposed to send 1 or a 0 depending on if it's a miss or a make. I also hooked up the LED to help me determine which case is occurring. Like it shows green then I know the prox sensor was the only sensor triggered.

I don't think the issue is with the setShot(), because when I used a serial bluetooth monitor to see what values were being sent, I got: 0xff = miss and 0xfe= score. I think the underlying issue is what I'm reading from the App.

The sensors are hooked on to the UNO and it's supposed to send 1 or a 0 depending on if it's a miss or a make.

Is it not setShot() which is doing the sending?

If instead of setShot(int mode) you use setShot(char mode) what do you see at the Android end.

setShot('1');
setShot('0');