Pages

Saturday, June 10, 2023

Jdy-31 SPP bt module

 This is about JDY-31, an SPP bluetooth module. 

This is cheap bluetooth module compared to   HC-06 which is claimed to be pin-compatible.

My Experience

I bought this because this is cheap. And serve its purpose. Just to replace USB-to-TTL module, then I can connect my device using bluetooth instead of wired one. This especially important to isolate the device (providing electrical isolation).

Unfortunately, I spent 3 days to configure this module until I found the way.

Why

I need to configure this device because it baudrates doesn't match the device. The module's baud is default 9600 bps. So I need to change it. Besides, it would be cool to change the broadcast name.

The result

I am successfully configures the module. here what is need to be considered:

  1. The default pairing pin is 1234, in case you doesn't found the manual. Yes, this module is sold without packaging.
  2. Check the voltage. In case you forgot, UART begins with high logic, start bit is low. So RX of BT is connected with TX of device, and logic is high.
  3. This module is slave device. Means it cannot initiate connection. 
  4. The configuration uses AT command. So you need to connect with other device to configure. I use USB-to-TTL module to configure using PC.
  5. AT command is case sensitive.
  6. AT command must ends with CRLF or 0x0D0A.
  7. JDY-31 only respond to right command. So entering AT will not respond. Comparing other modules which may responds OK.
  8. The command needs to sent using burst mode. Means the AT prefix until CRLF must not have significant delay. I don't know the exact amount. 
    1. Realtime mode: the character is sent as you type. Typing 'A' will be sent immediately. Many terminal application use this mode.
    2. Burst mode: Sent only done when user press send button. Terraterm use 'broadcast' for this mode.
  9. The AT command only works if not connected. Unfortunately, no pin for indicating the connected state. Only LED which is blinked. When connected, obviously the command will be sent plainly to the connected master.
  10. No difference between unpaired or paired.
So that is the conclusion.

Commands I use
Here some command I use:
  • AT+VERSION
    • connected: will send AT+VERSION to master device.
    • unconnected: will respond +VERSION=JDY-31-V1.35,Bluetooth V3.0
  • AT+BAUD. Setting baud rate to 115200 bps: AT+BAUD8
    • connected: will send entire command to master device.
    • unconnected: will respond +OK
    • query command AT+BAUD, reponse +BAUD=8
    • the default is BAUD4 for 9600 bps.
    • Note: the actual baud is not changed until the device is restarted. You can confirm this by sending AT+VERSION. If the modules respond, means the baud is not changed. Try to change the terminal baud rate setting. And see if it respond. Then unpower the module and re power it. Try sending AT command again. This also means the setting is kept even the module is unpowered. No need initialization.
  • AT+DISC: disconnect the bluetooth's serial connection. This only AT command valid when connected.
    • connected: respond +DISC=SUCCESS and broke transmit connection. Actually it kept connected, only cannot transmit, only receive.
    • unconnected or broke transmit: no response.
    • To normalize this state, use soft reset AT+RESET. Or hardware reset by unpower-repowering module. Module will respond +OK for soft reset. The connected device will respond with connection lost.

Wednesday, July 28, 2010

how to transfer 2 byte data

Sometimes you want to send 2 byte data or more. But we all know that many transfer medium like serial, I2C, CAN bus, bluetooth, etc; only allows use 1 byte data transfer only. So how to send integer value into byte medium? One way is converting into a sequence of character. Another way is splitting the data per bytes. For example, sending integer16 into byteHi and byteLo. It may easy if using assembly languages.
This time I'll show you how to send integer data from microcontroller to PC. I'm using C language in the microcontroller, and C# in the PC.
The key of these processes are 16 bit to 8 bit converter.

On the PC, using C#
memory mapping
//using System.Runtime.InteropServices
struct unionStruct {
   [FieldOffset(0)]
   public short bigVal;
   [FieldOffset(0)]
   public byte smallLow;
   [FieldOffset(1)]
   public byte smallHi;
}

Basically, we create struct. But somehow, we make one field is overlapped in the memory. This is the splitting work. As shown on the picture, bigVal is overlapped with the memory of smallLow and smallHi. In the other words, when we put a value in the smallLow, we can access it from smallLow or from bigVal. When we put 0x12 in the smallLow, it's same like we put 0x0012 in the bigVal. When we put 0x34 in the smallHi, then, in the bigVal will be read 0x3400. So if we put 0x1234 in the bigVal, then we can read the low byte in the smallLow which has the value of 0x34. And also we can read the high byte in the smallHi which has the value of 0x12. It has the same principles on C language.

On the microcontroller, using C
typedef struct {
memory mapping
   unsigned char lo;
   unsigned char hi;
}hilo_t;

typedef union {
   unsigned int besar;
   hilo_t  kecil;
}hilo_ut;

In the C language, we can't control the field offset. So we can create a structure that has 2 byte field. And then we put the structure in the union to make it overlapped with 2 byte memory.

How it works?
To send data, make sure the sequence is same for the microcntroller and the PC.This to avoid misunderstanding between PC and microcontroller of how to put the high byte and the low byte.
  1. Splitting 16-bit data to send to PC.
    hilo_ut byteInterface; //declaration
    byteInterface.besar = data16;   //put 16-bit data
    send(byteInterface.kecil.lo);      //send low byte first
    send(byteInterface.kecil.hi);      //send high byte
  2. Assembly two 8-bit data into 16-bit data in the PC
    unionStruct byteInterface = new byteInterface();  //declaration
    byteInterface.smallLow = read();   //read low byte first because microcontroller sends low byte first
    byteInterface.smallHi = read();      //read high byte
    short needee = byteInterface.bigVal; //read the 16-bit data
  3. Splitting 16-bit data to send to microcontroller.
    unionStruct byteInterface = new byteInterface();  //declaration
    byteInterface.bigVal = dataBig;   //put the 16-bit value
    send(byteInterface.smallLow);      //send low byte
    send(byteInterface.smallHi);      //send high byte
  4. Assembly two 8-bit data into 16-bit data from the PC
    hilo_ut byteInterface; //declaration
    byteInterface.kecil.lo = read();   //read low byte first
    byteInterface.kecil.hi = read();      //read high byte
    unsigned int nedee = byteInterface.besar;
That is how the easy way.