title: Android + ESP32 send data over bluetooth (BLE)
body: <p>I'm trying to send data from my android app to an esp32 over bluetooth (BLE) but i can't find the proper way to do it. All i can do for now is scan and find ble devices. My arduino code is working as i want (it receives the data properly) because i used another app which let me send data to ble devices so i know the arduino code is fine.</p>
  <p>I've been searching for days here and google how to achieve it but i still stucked in it. This is my code for now:</p>
  <p>Scanner:</p>
  <pre><code>class BluetoothFragment : Fragment() {
      private lateinit var binding: FragmentBluetoothBinding
      private var list : MutableList&lt;BluetoothDevice&gt; = ArrayList()
      private lateinit var  bluetoothAdapter : BluetoothAdapter
  
      override fun onCreateView(
          inflater: LayoutInflater, container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View? {
          // Inflate the layout for this fragment
          Log.d(&quot;DeviceListActivity&quot;, &quot;onCreate()&quot;)
          return inflater.inflate(R.layout.fragment_bluetooth, container, false)
      }
  
      // TODO: 19/05/2021 implementar listener en el recycler view para crear la conexión con el ble
  
      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
          binding = FragmentBluetoothBinding.bind(view)
          if (ContextCompat.checkSelfPermission(
                  requireContext(),
                  Manifest.permission.ACCESS_COARSE_LOCATION
              ) != PackageManager.PERMISSION_GRANTED
          ) {
              val permissions = arrayOf(
                  android.Manifest.permission.ACCESS_COARSE_LOCATION,
              )
              ActivityCompat.requestPermissions(requireActivity(), permissions, 0)
          }
  
          setRecyclerView(list)
      }
  
      private val bleScanner = object :ScanCallback() {
          override fun onScanResult(callbackType: Int, result: ScanResult?) {
              super.onScanResult(callbackType, result)
              Log.d(&quot;pepe&quot;,&quot;onScanResult: ${result?.device?.address} - ${result?.device?.name}&quot;)
              if(result?.device?.name?.isNotEmpty() == true){
                  var bluetoothDevice = result?.device?.name?.let { BluetoothDevice(it) }
                  if (bluetoothDevice != null) {
                      list.add(bluetoothDevice)
                      bluetoothAdapter.notifyDataSetChanged()
                  }
              }
          }
  
          override fun onBatchScanResults(results: MutableList&lt;ScanResult&gt;?) {
              super.onBatchScanResults(results)
              Log.d(&quot;DeviceListActivity&quot;,&quot;onBatchScanResults:${results.toString()}&quot;)
          }
  
          override fun onScanFailed(errorCode: Int) {
              super.onScanFailed(errorCode)
              Log.d(&quot;DeviceListActivity&quot;, &quot;onScanFailed: $errorCode&quot;)
          }
  
      }
  
      private val bluetoothLeScanner: BluetoothLeScanner
          get() {
              val bluetoothManager = requireActivity().getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
              val bluetoothAdapter = bluetoothManager.adapter
              return bluetoothAdapter.bluetoothLeScanner
          }
  
      class ListDevicesAdapter(context: Context?, resource: Int) : ArrayAdapter&lt;String&gt;(context!!, resource)
  
  
      override fun onStart() {
          Log.d(&quot;DeviceListActivity&quot;,&quot;onStart()&quot;)
          super.onStart()
          bluetoothLeScanner.startScan(bleScanner)
      }
  
      override fun onStop() {
          bluetoothLeScanner.stopScan(bleScanner)
          super.onStop()
      }
  
      private fun setRecyclerView(allCategories: List&lt;BluetoothDevice&gt;) {
          val layoutManager: RecyclerView.LayoutManager = LinearLayoutManager(context)
          binding.rvBluetooth.layoutManager = layoutManager
          bluetoothAdapter = BluetoothAdapter(allCategories)
          binding.rvBluetooth.adapter = bluetoothAdapter
      }
  }
  </code></pre>
  <p>Arduino code (I'm controlling a little car with it so thats why i have 5 different values):</p>
  <pre><code>#include &lt;BLEDevice.h&gt;
  #include &lt;BLEUtils.h&gt;
  #include &lt;BLEServer.h&gt;
  
  #define SERVICE_UUID        &quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&quot;
  #define CHARACTERISTIC_UUID &quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&quot;
  
  // Motor 1
  int motor1Pin1 = 23;
  int motor1Pin2 = 22;
  int enable1Pin = 21;
  
  // Motor 2
  int motor2Pin1 = 18;
  int motor2Pin2 = 19;
  int enable2Pin = 5;
  
  const int freq = 30000;
  const int pwmChannel = 0;
  const int resolution = 8;
  int dutyCycle = 200;
  
  class MyCallbacks: public BLECharacteristicCallbacks {
      void onWrite(BLECharacteristic *pCharacteristic) {
        std::string value = pCharacteristic-&gt;getValue();
  
        if (value.length() &gt; 0) {
          if (value[0] == '1') {
            dutyCycle = 200;
            Serial.println(&quot;Moving Forward&quot;);
            digitalWrite(motor1Pin1, LOW);
            digitalWrite(motor1Pin2, HIGH);
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, HIGH);
            while (dutyCycle &lt;= 255) {
              ledcWrite(pwmChannel, dutyCycle);
              dutyCycle = dutyCycle + 5;
              delay(500);
            }
  
          }
          if (value[0] == '4') {
            dutyCycle = 200;
            Serial.println(&quot;Moving Backwards&quot;);
            digitalWrite(motor1Pin1, HIGH);
            digitalWrite(motor1Pin2, LOW);
            digitalWrite(motor2Pin1, HIGH);
            digitalWrite(motor2Pin2, LOW);
            while (dutyCycle &lt;= 255) {
              ledcWrite(pwmChannel, dutyCycle);
              dutyCycle = dutyCycle + 5;
              delay(500);
            }
          }
          if (value[0] == '2') {
            dutyCycle = 100;
            Serial.println(&quot;Motor right&quot;);
            digitalWrite(motor1Pin1, LOW);
            digitalWrite(motor1Pin2, HIGH);
            digitalWrite(motor2Pin1, HIGH);
            digitalWrite(motor2Pin2, LOW);
          }
          if (value[0] == '3') {
            dutyCycle = 100;
            Serial.println(&quot;Motor left&quot;);
            digitalWrite(motor1Pin1, HIGH);
            digitalWrite(motor1Pin2, LOW);
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, HIGH);
          }
          if (value[0] == '0') {
            Serial.println(&quot;Motor stopped&quot;);
            digitalWrite(motor1Pin1, LOW);
            digitalWrite(motor1Pin2, LOW);
            digitalWrite(motor2Pin1, LOW);
            digitalWrite(motor2Pin2, LOW);
          }
        }
      }
  };
  
  
  void setup() {
    Serial.begin(115200);
    BLEDevice::init(&quot;Andruino&quot;);
    BLEServer *pServer = BLEDevice::createServer();
  
    BLEService *pService = pServer-&gt;createService(SERVICE_UUID);
  
    BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(
                                           CHARACTERISTIC_UUID,
                                           BLECharacteristic::PROPERTY_WRITE
                                         );
  
    pCharacteristic-&gt;setCallbacks(new MyCallbacks());
    pService-&gt;start();
  
    BLEAdvertising *pAdvertising = pServer-&gt;getAdvertising();
    pAdvertising-&gt;start();
  
    pinMode(motor1Pin1, OUTPUT);
    pinMode(motor1Pin2, OUTPUT);
    pinMode(enable1Pin, OUTPUT);
  
    pinMode(motor2Pin1, OUTPUT);
    pinMode(motor2Pin2, OUTPUT);
    pinMode(enable2Pin, OUTPUT);
  
    ledcSetup(pwmChannel, freq, resolution);
  
    ledcAttachPin(enable1Pin, pwmChannel);
    ledcAttachPin(enable2Pin, pwmChannel);
   
    ledcWrite(pwmChannel, dutyCycle);
  }
  
  void loop() {
  
  }
  </code></pre>
  <p>How could i send data from my android app to esp32 over bluetooth?</p>