What if play was not just a simple recreational activity but a necessity for the proper development of children?

Invited post, written by Sacha Benrabia, Cassandra Dumas, Laura Lalieve

Through play, children can develop self-confidence, collaboration, emotional expression and initiative. It also contributes to cognitive, physical, social and emotional well-being. Researh shown that through play, children develop many aspects, from their motor skills to their language, as well as their intellectual and social development.

Intellectual development

By stimulating children’s curiosity, games play a key role in memory development. In particular, construction games help develop the logical part of the brain. Finally, through play, children develop their brains and their cerebral plasticity.

Social Development

Play is an educational and pedagogical activity that contributes to the emotional, moral and social development of the child. It is also a way of understanding reality with its norms, rules and values. Play contributes to the structuring of the child, a key stage that marks his or her social relationship with his or her present and future environment.

Motor and sensory development

The experience gained through play is associated with improved spatial skills, including better geometric thinking. Through play, children begin to crawl and then walk normally, and develop skills in climbing, balancing, throwing, aiming and coordinating with obstacles along the way.

Language development

When children play with peers, they are communicating in some way with others. In this sense, play is a primitive system of communication through which emotions, dreams and fears can be expressed. More generally, play is a way of calling out to others through a symbol. By having fun with toys of various and sometimes atypical shapes and colors, children enrich their vocabulary and their understanding of the shapes and colors that surround them.

What about Coral?

Coral is a tangible biofeedback interface in the form of a construction set. Equipped with physiological sensors, it allows children to discover their physiological data and share them with others. Its colors and varied shapes arouse the curiosity of the youngest and keep them awake.

Through biofeedback, children can discover the effects of their mental states and emotions on their physiology and learn to regulate it in a healthier way.

Coral allows for motor, social, language and intellectual development of the child while offering a fun activity that appeals to the child’s imagination.

Sacha, Cassandra and Laura contributed to the third iteration of Coral, investigating how it could be used more specifically with children.

Bibliography

COUZON Nathalie, « Le pouvoir du jeu dans le développement des jeunes enfants », 2018 

http://rire.ctreq.qc.ca/2018/12/pouvoir-jeux/ 

EKIN Cansu C., CAGILTAY Kursat & KARASU Necdet, « Effectiveness of smart toy applications in teaching children with intellectual disability », Journal of Systems Architecture, 2018, n°89, p.41-48

https://www.researchgate.net/publication/326509360_Effectiveness_of_Smart_Toy_Applications_in_Teaching_Children_with_Intellectual_Disability

GAUSSOT Ludovic. « Le jeu de l’enfant et la construction sociale de la réalité », Le Carnet PSY, vol. 62, n°2, p.22-29, 2001

https://www.cairn.info/revue-spirale-2002-4-page-39.htm

VERDINE Brian, ZIMMERMANN Laura & al. « Effects of Geometric Toy Design on Parent-Child Interactions and Spatial Language », Early Childhood Research Quarterly, 2018

https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6289199/

METRA Maryse, « Le jeu dans le développement affectif, cognitif, corporel et social de l’enfant », UFAIS Lyon, 2006

https://aefe-zoneafriquecentrale.net/IMG/pdf/jeu_et_developpement_de_l-_enfant.pdf

If you want to know more about this concept, here are some known names : Mildred Parten, Nathalie Nader-Grosbois, Sandrine Vincent, Jean Piaget

Get your sensor data on your web browser using Web Bluetooth

Web bluetooth has been around since a few years now, and enables people to exchange data with sensors and connected devices.

However, not every browser supports Web Bluetooth juste yet. You can find here a list of supported web browsers. On iOS you can install the app Bluefy to enable the use of Web Bluetooth.

We will detail here how to connect to a heart rate sensor and display the provided information on your web page, using only javascript, without any installation required by end users.

First, you will create your usual suspects: index.html, style.css and script.js files.

In your index.html, you will only need a minimal code, with a button and an empty paragraph.

<!DOCTYPE html>
<html>

    <head>
        <meta charset = "utf-8">
        <title>My first Web Ble app</title>
        <meta name = "author" content = "Ullo Labs">
        <meta name = "description" content = "Simple app using web bluetooth to connect to a remote heart sensor">
        <meta name = "viewport" content = "width=device-width, initial-scale=1">
        <link href="./style.css" rel="stylesheet">
    </head>

    <body>
        <button id = "connectButton">Connect</button>
        <p id = "dataText"></p>    
        <script src = "./script.js"></script>
    </body>

</html>

This simple CSS content should be more than enough for now:

#connectButton {
    cursor: not-allowed ;
}

Now, let’s see our javascript content.

First, you will have to check if your browser supports the web bluetooth.

This can simply be done with the following line:

let p = document.getElementById("dataText") ;
if (navigator.bluetooth === undefined) {
    p.textContent = "Web bluetooth is not supported" ;
}
else {
    let button = document.getElementById("connectButton") ;
    button.style.cursor = "pointer" ;
    // the rest of your code
}

Now, let’s add a callback function to our button:

let p = document.getElementById("dataText") ;
if (navigator.bluetooth === undefined) {
    p.textContent = "Web bluetooth is not supported" ;
}
else {
    let button = document.getElementById("connectButton") ;
    button.style.cursor = "pointer" ;
    
    onClickEvent = (event) => {
        console.log("clicked") ;
    }

    button.addEventListener('click', onClickEvent ) ;
}

Here, we will simply display the word clicked on our console.

But we want now to connect to our device and listen for incoming data.

This will be done with the following lines:

handleCharacteristicValueChanged = (event) => {
    // we will add code here later to process the incoming data
}

onClickEvent = () => {
    navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] }) // we filter the devices, displaying only those with heartrate services
    .then(device => device.gatt.connect()) // after the user select a device, we return the selected one
    .then(server => server.getPrimaryService('heart_rate')) // we get the service
    .then(service => service.getCharacteristic('heart_rate_measurement')) // then the characteristics
    .then(characteristic => characteristic.startNotifications())
    .then(characteristic => {          
        characteristic.addEventListener('characteristicvaluechanged', handleCharacteristicValueChanged) ; // then we subscribe to the characteristic notifications
    })                                                                                                      // and set the callback function
    .catch(error => { console.error(error); }) ; // we display the errors on the console
}
button.addEventListener('click', onClickEvent ) ;

Now, we only need to process the incoming data:

handleCharacteristicValueChanged = (event) => {
    let value = event.target.value ; // a dataviewer object is provided by the object event
    let heartrate = value.getUint8(1) ; // we select the eight bytes that contain the heartrate informations
    p.textContent = heartrate + " BPM" ; // and display it
}

So, at the end, your javascript file will look like that :

let p = document.getElementById("dataText") ;
if (navigator.bluetooth === undefined) {
    p.textContent = "Web bluetooth is not supported" ;
}
else {
    let button = document.getElementById("connectButton") ;
    button.style.cursor = "pointer" ;

    handleCharacteristicValueChanged = (event) => {
        let value = event.target.value ; // a dataviewer object is provided by the object event
        let heartrate = value.getUint8(1) ; // we select the eight bytes that contain the heartrate informations
        p.textContent = heartrate + " BPM" ; // and display it
    }

    onClickEvent = () => {
        navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] }) // we filter the devices, displaying only those with heartrate services
        .then(device => device.gatt.connect()) // after the user select a device, we return the selected one
        .then(server => server.getPrimaryService('heart_rate')) // we get the service
        .then(service => service.getCharacteristic('heart_rate_measurement')) // then the characteristics
        .then(characteristic => characteristic.startNotifications())
        .then(characteristic => {          
            characteristic.addEventListener('characteristicvaluechanged', handleCharacteristicValueChanged) ; // then we subscribe to the characteristic notifications
        })                                                                                                    // and set the callback function
        .catch(error => { console.error(error); }) ; // we display the errors on the console
    }
    button.addEventListener('click', onClickEvent ) ;
}

and once connected you should see your BPM on your web page:

Bonus: we would love to see a little heart on our screen!

Juste add a sprite in your HTML:

<!DOCTYPE html>
<html>

    <head>
        <meta charset = "utf-8">
        <title>My first Web Ble app</title>
        <meta name = "author" content = "Ullo Labs">
        <meta name = "description" content = "Simple app using web bluetooth to connect to a remote heart sensor">
        <meta name = "viewport" content = "width=device-width, initial-scale=1">
        <link href="./style.css" rel="stylesheet">
    </head>

    <body>
        <button id = "connectButton">Connect</button>
        <p id = "dataText"></p>
        <img id = "heartSprite" src = "./heart.png" />
        <script src = "./script.js"></script>
    </body>

</html>

Some additional CSS:

#connectButton {
    cursor: not-allowed ;
}

#heartSprite {
    width : 64px ;
    height : 64px ;
}

And a little bit of javascript:

var BPM = 0.0 ;
var heart = document.getElementById("heartSprite") ;
let p = document.getElementById("dataText") ;

if (navigator.bluetooth === undefined) {
    p.textContent = "Web bluetooth is not supported" ;
}
else {
    let button = document.getElementById("connectButton") ;
    button.style.cursor = "pointer" ;

    handleCharacteristicValueChanged = (event) => {
        let value = event.target.value ; // a dataviewer object is provided by the object event
        let heartrate = value.getUint8(1) ; // we select the eight bytes that contain the heartrate informations
        p.textContent = heartrate + " BPM" ; // and display it
        BPM = heartrate ;
    }

    onClickEvent = () => {
        navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] }) // we filter the devices, displaying only those with heartrate services
        .then(device => device.gatt.connect()) // after the user select a device, we return the selected one
        .then(server => server.getPrimaryService('heart_rate')) // we get the service
        .then(service => service.getCharacteristic('heart_rate_measurement')) // then the characteristics
        .then(characteristic => characteristic.startNotifications())
        .then(characteristic => {          
            characteristic.addEventListener('characteristicvaluechanged', handleCharacteristicValueChanged) ; // then we subscribe to the characteristic notifications
        })                                                                                                    // and set the callback function
        .catch(error => { console.error(error); }) ; // we display the errors on the console
    }
    button.addEventListener('click', onClickEvent ) ;

    let startTime = performance.now() ;
    let step = 0 ;
    updateHeartSize = () => {
        if (BPM > 0)
        {
            let ibi = 60./BPM * 1000 ;
            let elapsedTime = performance.now() - startTime ;
            let scaleUp = 1.1 ;
            let scaleDown = (1/scaleUp).toFixed(2) ;

            if (elapsedTime < ibi * 0.05 && step == 0 )
            {
                step++ ;
                heartSprite.style.transform = "scale(" + scaleUp + ")" ;
            }
            else if ( elapsedTime > ibi * 0.05 && elapsedTime < ibi * 0.22 && step == 1)
            {
                step++ ;
                heartSprite.style.transform = "scale(" + scaleDown + ")" ;
            }
            else if ( elapsedTime > ibi * 0.22 && elapsedTime < ibi * 0.26 && step == 2)
            {
                step++ ;
                heartSprite.style.transform = "scale(" + scaleUp + ")" ;
            }
            else if (elapsedTime > ibi * 0.26 && step == 3)
            {
                step++ ;
                heartSprite.style.transform = "scale(" + scaleDown + ")" ;
            }
            if (elapsedTime > ibi)
            {
                step = 0 ;
                startTime = performance.now() ;
            }
        }
        globalID = requestAnimationFrame(updateHeartSize) ;
    } ;

    let globalID = requestAnimationFrame(updateHeartSize) ;
}

Voilà!

Check the source code on https://github.com/UlloLabs/tutorial.HR-WebBLE/ and see the result on https://ullolabs.github.io/tutorial.HR-WebBLE/.