cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically generate and display QR code

BGuth.1
Senior

I am using 4.16.1 TouchGFX designer tool. Is it possible to generate QR code for a given string and PIN code in run time and display? Please advice.

8 REPLIES 8
MM..1
Chief III
ktrofimo
Senior III

I have used https://github.com/ricmoo/QRCode library.

Made a simple wrapper class QRCode.cpp

#include <gui/widgets/qrcode/QRCode.hpp>
#include <gui/widgets/qrcode/qrcode.h>
#include <stdlib.h>
 
QR::QR( const char * text )
{
	 qrcode = new QRCode();
	 qrcodeData = (uint8_t *)malloc( qrcode_getBufferSize(1) );
	 qrcode_initText( qrcode, qrcodeData, 1, 0, text );
}
 
QR::~QR()
{
	free( qrcodeData );
	delete qrcode;
}
 
bool QR::at(uint16_t x, uint16_t y) const
{
    return qrcode_getModule( qrcode, x, y );
}
 
uint16_t QR::getWidth() const
{
    return qrcode->size;
}
 
uint16_t QR::getHeight() const
{
    return qrcode->size;
}

and a custom widget QRCodeWidget.cpp

#include <gui/widgets/qrcode/QRCodeWidget.hpp>
#include <touchgfx/hal/HAL.hpp>
 
QRCodeWidget::QRCodeWidget() : 
    code(0),
    scale(1)
{
}
 
void QRCodeWidget::setQRCode(QR *qrCode)
{
    code = qrCode;
    updateSize();
}
 
void QRCodeWidget::draw(const touchgfx::Rect& invalidatedArea) const
{
    if(!code)
    {
        return;
    }
 
    touchgfx::Rect absolute = getAbsoluteRect();
 
    uint16_t *framebuffer = touchgfx::HAL::getInstance()->lockFrameBuffer();
 
    for(int y = invalidatedArea.y; y < invalidatedArea.bottom(); y++)
    {
        for(int x = invalidatedArea.x; x < invalidatedArea.right(); x++)
        {
        	int offset=0;
        	switch(touchgfx::HAL::DISPLAY_ROTATION)
        	{
        	case touchgfx::rotate0:
        		offset = absolute.x + x + (absolute.y + y) * touchgfx::HAL::DISPLAY_WIDTH;
        		break;
        	case touchgfx::rotate90:
        		offset = (touchgfx::HAL::DISPLAY_WIDTH-(absolute.x + x)-1) * touchgfx::HAL::DISPLAY_HEIGHT
					+ (absolute.y + y);
        		break;
        	}
    		framebuffer[offset] = code->at(x / scale, y / scale) ? 0x0000 : 0xffff;
 
        }
    }
 
    touchgfx::HAL::getInstance()->unlockFrameBuffer();
}
 
touchgfx::Rect QRCodeWidget::getSolidRect() const
{
    return touchgfx::Rect(0,0,getWidth(), getHeight());
}
 
void QRCodeWidget::setScale(uint8_t s)
{
    scale = s;
    updateSize();
}
 
void QRCodeWidget::updateSize()
{
    if(code)
    {
        setWidth(code->getWidth() * scale);
        setHeight(code->getHeight() * scale);
    }    
}

Using is quite straightforward:

#include <gui/common/QrCodeWidget.hpp>
#include <gui/model/QrCode.hpp>
 
QRCodeWidget qrCode;
QR *code;
 
char string[50];
sprintf( string, "http://iwtm.com" );
code = new QR( string );
qrCode.setXY(10,20);
qrCode.setQRCode(code);
qrCode.setScale(8);
add(qrCode);

Thank you for your reply. I appreciate it. Just so I understand it better, would you mind sharing QrCodeWidget.hpp and QrCode.hpp too please.

QRCode.hpp

#ifndef QR_CODE_HPP
#define QR_CODE_HPP
 
#include <touchgfx/hal/Types.hpp>
#include "qrcode.h"
 
/**
* @class QRCode
* 
* @brief An interface for getting the value of a qr code at a particular x,y position
*
*        This implementation generates random values for the different x,y coordinates.
*        A real qr code will probably save the qr code values in an array like structure and report these instead.
*/
class QR
{
public:
	QR( const char * text );
	~QR();
    /**
     * @fn bool QRCode::at(uint16_t x, uint16_t y);
     *
     * @brief Get the qr code value at a particular coordinate
     *
     * @param x x coordinate
     * @param y y coordinate
     *
     * @return The value of the qr code at the supplied coordinate
     */
    bool at(uint16_t x, uint16_t y) const;
 
    /**
     * @fn uint16_t QRCode::getWidth();
     *
     * @brief Get the width of the qr code
     *
     * @return The width
     */
    uint16_t getWidth() const;
 
    /**
     * @fn uint16_t QRCode::getHeight();
     *
     * @brief Get the height of the qr code
     *
     * @return The height
     */
    uint16_t getHeight() const;
    QRCode   *qrcode;
    uint8_t  *qrcodeData;
};
 
#endif

QRCodeWidget.hpp

#ifndef QR_CODE_WIDGET_HPP
#define QR_CODE_WIDGET_HPP
 
#include <touchgfx/widgets/Widget.hpp>
#include <gui/model/QRCode.hpp>
#include <touchgfx/hal/Types.hpp>
 
/**
* @class QRCodeWidget
* 
* @brief A widget for displaying a QRCode
* 
*        The widget will be drawn in black and white.
*        The values of the supplied QRCode will determine the appearance
*        The widget can be scaled in order to display the qr code in an appropriate size
*
*        @sa touchgfx::Widget
*/
class QRCodeWidget : public touchgfx::Widget
{
public:
    /**
     * @fn QRCodeWidget::QRCodeWidget();
     *
     * @brief Default constructor
     */
    QRCodeWidget();
 
    /**
     * @fn virtual void QRCodeWidget::draw(const touchgfx::Rect& invalidatedArea) const;
     *
     * @brief Draw the part of the qr code that is inside the invalidated area
     *        
     * @param invalidatedArea The region of this drawable that needs to be redrawn
     *
     * @sa touchgfx::Drawable
     */
    virtual void draw(const touchgfx::Rect& invalidatedArea) const;
 
    /**
     * @fn virtual touchgfx::Rect QRCodeWidget::getSolidRect() const;
     *
     * @brief Report this widget as being completely solid
     *
     * @return The solid rect.
     */
    virtual touchgfx::Rect getSolidRect() const;
 
    /**
     * @fn void QRCodeWidget::setQRCode(QRCode *code);
     *
     * @brief Set the qr code to display
     */
    void setQRCode(QR *code);
 
    /**
     * @fn void QRCodeWidget::setScale(uint8_t s);
     *
     * @brief Set the scaling factor of the widget
     */
    void setScale(uint8_t s);
 
private:
    void updateSize();
 
    QR *code;
    uint8_t scale;
};
 
#endif

I am trying it out. I included qrcode.c and qrcode.h from the https://github.com/ricmoo/QRCode library, and your QrCode.cpp, QrCode.hpp, QRCodeWidget.cpp and QRCodeWidget.hpp in my TouchGFX environment. I get below error. Am I missing any other files? Please advice.

0693W00000WIQpYQAX.png

Where did you place .h and .hpp files? Are they in project paths? Are .c and .cpp included in project?

These are regular compiler errors - check your project settings...​

I first put source and includes at TouchGFX\gui\src\widget\qrcode and TouchGFX\gui\include\gui\widget\qrcode respectively. That seems to be one folder level deep than necessary. So I moved to TouchGFX\gui\src\qrcode and TouchGFX\gui\include\gui\qrcode. Now TouchGFX sees them and tries to compile them when I click run simulator button.

Is this how you placed too? how did you tell TouchGFX to treat qrcode.c as a C file and not C++?

Hi, would you mind to share with me some many files, which they missing for me.

- Widget.cpp & .hpp

- Types.cpp & .hpp

- HAL.cpp & .hpp

Thanks in advanced

Mahdi