I'm well on my way on learning coding for Arduino.
For the following case I Googled my ass off, but can't find any helpful answer.
So, asking here. Maybe you can help me with some terminology to Google, or direct links where this is elaborated.
I want to compress the following code. The predefined colors have to be as they are.
All variables have the same prefix, namely COLOR_. Is there any way to compress the part that is in the setup?
See following link.
// Define the colors of remote control in RGB values
// R G B
#define COLOR_0 { 0, 0, 0}
#define COLOR_1 {255, 0, 0} // Red
#define COLOR_2 {255, 160, 25} // Orange
#define COLOR_3 {255, 255, 0} // Yellow
#define COLOR_4 {127, 255, 127} // Pink
#define COLOR_5 { 0, 255, 0} // Green
#define COLOR_6 { 0, 255, 255} // Cyan
#define COLOR_7 { 0, 127, 255} // Light blue
#define COLOR_8 { 0, 0, 255} // Blue
#define COLOR_9 {191, 0, 255} // light green
uint16_t RGB_565(uint8_t red, uint8_t green, uint8_t blue){
// 16-bit value to express the RGB565-color:
// |R|R|R|R|R|G|G|G|G|G|G|B|B|B|B|B|
uint16_t red_565 = red / 8;
uint16_t green_565 = green / 4;
uint16_t blue_565 = blue / 8;
uint16_t mixed_565 = (red_565 << 11) | (green_565 << 5) | blue_565;
return mixed_565;
}
void setup(){
// Convert the preset colors to a RGB565-value
const uint8_t tint_1[] = COLOR_1;
uint16_t color_1 = RGB_565(tint_1[0], tint_1[1], tint_1[2]);
const uint8_t tint_2[] = COLOR_2;
uint16_t color_2 = RGB_565(tint_2[0], tint_2[1], tint_2[2]);
const uint8_t tint_3[] = COLOR_3;
uint16_t color_3 = RGB_565(tint_3[0], tint_3[1], tint_3[2]);
const uint8_t tint_4[] = COLOR_4;
uint16_t color_4 = RGB_565(tint_4[0], tint_4[1], tint_4[2]);
// etc...
// This part should be able to be compressed
}
void loop(){
// Not relevant
}
What about
#define COLOR_1 255, 0, 0
Then simply call
RGB_565(COLOR_1);
When I read output from the fragment shader:
#version 300 es
precision highp float;
precision highp int;
out int outColor[2];
void main() {
outColor[0] = 5;
outColor[1] = 2;
}
rendered into a 32 bit integer RG texture, I find that only the 5s have been written but not the 2s. Presumably I've got some format specifier wrong somewhere. Or I might be attaching the framebuffer to the wrong thing (gl.COLOR_ATTACHMENT0). I've tried varying various arguments but most changes that I make result in nothing coming out due to formats not lining up. It might be that I need to change 3 constants in tandem.
Here's my self-contained source. The output I want is an array alternatingbetween 5 and 2. Instead, I get an array alternating between 5 and semi-random large constants and 0.
let canvas /** #type {HTMLCanvasElement} */ = document.createElement('canvas');
let gl = canvas.getContext("webgl2");
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, `#version 300 es
in vec4 a_position;
void main() {
gl_Position = a_position;
}
`);
gl.compileShader(vertexShader);
console.assert(gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS), "Vertex shader compile failed.");
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, `#version 300 es
precision highp float;
precision highp int;
out int outColor[2];
void main() {
outColor[0] = 5;
outColor[1] = 2;
}
`);
gl.compileShader(fragmentShader);
let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
let positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-3, -1, 1, 3, 1, -1]), gl.STATIC_DRAW);
let positionAttributeLocation = gl.getAttribLocation(program, "a_position");
let vao = gl.createVertexArray();
gl.bindVertexArray(vao);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
let w = 4;
let h = 4;
let texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RG32I, w, h, 0, gl.RG_INTEGER, gl.INT, null);
let frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.useProgram(program);
gl.viewport(0, 0, w, h);
gl.drawArrays(gl.TRIANGLES, 0, 3);
let outputBuffer = new Int32Array(w*h*2);
gl.readPixels(0, 0, w, h, gl.RG_INTEGER, gl.INT, outputBuffer);
console.log(outputBuffer);
Arrayed outputs like out int outColor[2]; are used for outputting to multiple render targets. In your case, two render targets with one channel each, because you've used a scalar type.
To express a single render target with two channels, try out ivec2 outColor;.
Some students from my school are working on a project to measure vibrations (eg. earthquakes) and print the results from two sensors (Piezo knock and vibration sensor) to lcd shield. They probably compiled some codes from the internet. Their original code was like this:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int referansDegeri = 800;
int knockSensor = 0;
int val = 0;
int sensorLevel = map;
int statePin = LOW;
int THRESHOLD = 100;
const int analogPin = A0;
int vib_pin=7;
void setup()
{
int sensorReading = analogRead(analogPin);
// map the result to a range from 0 to the number of LEDs:
int sensorLevel = map(sensorReading, 0, 1023, 0, sensorCount);
pinMode(vib_pin,INPUT);
Serial.begin(9600);
}
void loop()
{
int sensorDegeri = analogRead(A0);
Serial.print(sensorDegeri); //Okuduğumuz değer ekrana yazdırılıyor
if (sensorDegeri >= referansDegeri){
Serial.println("siddetli sarsinti");
}
else{
Serial.println("dusuk sarsinti");
}
delay(1);
}
val = analogRead(knockSensor);
if (val >= THRESHOLD) {
statePin = !statePin;
digitalWrite(ledPin, statePin);
Serial.println("Knock!");
delay(100);
int val;
val=digitalRead(vib_pin);
if(val==1)
{
digitalWrite(led_pin,HIGH);
delay(1000);
digitalWrite(led_pin,LOW);
delay(1000);
}
else
digitalWrite(led_pin,LOW);
}
This code gave this error (exit status):
'sensorCount' was not declared in this scope
Knowing that the students have one knock sensor, I changed the sensorCount to 1 while mapping it so it would seem
int sensorLevel = map(sensorReading, 0, 1023, 0, 1);
then it started giving this error (exit status):
'val' does not name a type
I made some search however, could not find a specific result so cannot fix the problem. But I believe it is important to mention that students were using LED Bar Graph previously, alongside LCD shield, but they have now removed it.
Update: So I'm getting the error: "expected initializer before 'fsrAnalogPin'" with this code. Can someone help me sort this out?
// testshapes demo for Adafruit RGBmatrixPanel library.
// Demonstrates the drawing abilities of the RGBmatrixPanel library.
// For 32x32 RGB LED matrix:
// http://www.adafruit.com/products/607
// Written by Limor Fried/Ladyada & Phil Burgess/PaintYourDragon
// for Adafruit Industries.
// BSD license, all text above must be included in any redistribution.
#include <Adafruit_GFX.h> // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
// If your 32x32 matrix has the SINGLE HEADER input,
// use this pinout:
#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
#define D A3
#define PULLUP true //use the AVR's internal pullup resistor
#define INVERT true //low level means fsr pressed
#define DEBOUNCE_TIME 50 //milliseconds
// If your matrix has the DOUBLE HEADER input, use:
//#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
//#define LAT 9
//#define OE 10
//#define A A3
//#define B A2
//#define C A1
//#define D A0
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);
void loop(){
Serial.begin(9600);
matrix.begin();
// draw a pixel in solid white
matrix.drawPixel(0, 0, matrix.Color333(7, 7, 7));
delay(500);
// fix the screen with green
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 7, 0));
delay(500);
// draw a box in yellow
matrix.drawRect(0, 0, 32, 32, matrix.Color333(7, 7, 0));
delay(500);
// draw an 'X' in red
matrix.drawLine(0, 0, 31, 31, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 0, 31, matrix.Color333(7, 0, 0));
delay(500);
// draw a blue circle
matrix.drawCircle(10, 10, 10, matrix.Color333(0, 0, 7));
delay(500);
// fill a violet circle
matrix.fillCircle(21, 21, 10, matrix.Color333(7, 0, 7));
delay(500);
// fill the screen with 'black'
matrix.fillScreen(matrix.Color333(0, 0, 0));
// draw some text!
matrix.setCursor(1, 0); // start at top left, with one pixel of spacing
matrix.setTextSize(1); // size 1 == 8 pixels high
matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.println("FIST");
matrix.println(" BUMP");
// print each letter with a rainbow color
matrix.setTextColor(matrix.Color333(7,0,0));
matrix.print('C');
matrix.setTextColor(matrix.Color333(7,4,0));
matrix.print('O');
matrix.setTextColor(matrix.Color333(7,7,0));
matrix.print('U');
matrix.setTextColor(matrix.Color333(4,7,0));
matrix.print('N');
matrix.setTextColor(matrix.Color333(0,7,0));
matrix.println('T');
{
const int fsr_pin = A4; //connect fsr from this pin to ground
int read fsrAnalogPin = 4;
fsr_pin.read();
if( fsr_pin.wasPressed() ){
counter = counter + 1
matrix.setTextColor( matrix.Color333(0,7,7) );
matrix.print( counter )
}
}
// whew!
}
void loop() {
// do nothing
}
if someone can help me with my code I would be very grateful. What I'm trying to do is: Using a force-sensitive resistor, I want to count a given amount of pressure on the FSR with an arduino, that then displays each tap on an LED matrix. In other words, I have a glove with an FSR on it, and I want to count "fist bumps" that then display on an 32x32 Adafruit LED matrix.
Here's an example of what I want it to look like:
https://drive.google.com/file/d/0B4kq-ADrtz4mSzNWUTJoNGlBSU0/view?usp=sharing
That is just a static number on the bottom though. I need help making the code to connect a counting variable to the FSR "bumps." It's probably pretty simple but I'm entirely new to this so it's a lot to learn. So any help is appreciated
Here is what I have for code:
// testshapes demo for Adafruit RGBmatrixPanel library.
// Demonstrates the drawing abilities of the RGBmatrixPanel library.
// For 32x32 RGB LED matrix:
// http://www.adafruit.com/products/607
// Written by Limor Fried/Ladyada & Phil Burgess/PaintYourDragon
// for Adafruit Industries.
// BSD license, all text above must be included in any redistribution.
#include <Adafruit_GFX.h> // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
// If your 32x32 matrix has the SINGLE HEADER input,
// use this pinout:
#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
#define D A3
#define FSR_PIN A4 //connect fsr from this pin to ground
#define PULLUP true //use the AVR's internal pullup resistor
#define INVERT true //low level means fsr pressed
#define DEBOUNCE_TIME 50 //milliseconds
// If your matrix has the DOUBLE HEADER input, use:
//#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
//#define LAT 9
//#define OE 10
//#define A A3
//#define B A2
//#define C A1
//#define D A0
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);
void setup() {
Serial.begin(9600);
matrix.begin();
// draw a pixel in solid white
matrix.drawPixel(0, 0, matrix.Color333(7, 7, 7));
delay(500);
// fix the screen with green
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 7, 0));
delay(500);
// draw a box in yellow
matrix.drawRect(0, 0, 32, 32, matrix.Color333(7, 7, 0));
delay(500);
// draw an 'X' in red
matrix.drawLine(0, 0, 31, 31, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 0, 31, matrix.Color333(7, 0, 0));
delay(500);
// draw a blue circle
matrix.drawCircle(10, 10, 10, matrix.Color333(0, 0, 7));
delay(500);
// fill a violet circle
matrix.fillCircle(21, 21, 10, matrix.Color333(7, 0, 7));
delay(500);
// fill the screen with 'black'
matrix.fillScreen(matrix.Color333(0, 0, 0));
// draw some text!
matrix.setCursor(1, 0); // start at top left, with one pixel of spacing
matrix.setTextSize(1); // size 1 == 8 pixels high
matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.println("FIST");
matrix.println(" BUMP");
// print each letter with a rainbow color
matrix.setTextColor(matrix.Color333(7,0,0));
matrix.print('C');
matrix.setTextColor(matrix.Color333(7,4,0));
matrix.print('O');
matrix.setTextColor(matrix.Color333(7,7,0));
matrix.print('U');
matrix.setTextColor(matrix.Color333(4,7,0));
matrix.print('N');
matrix.setTextColor(matrix.Color333(0,7,0));
matrix.println('T');
void loop(void)
{
fsr.read();
if (fsr.wasPressed()) {
Serial.print(++counter, DEC);
Serial.println(" steps");
}
matrix.setTextColor(matrix.Color333(0,7,7));
matrix.print("29291");
// whew!
}
void loop() {
// do nothing
}
Firstly, you need to remove the loop() method from setup().
In the void loop() method, making following changes should get things working.
void loop(){
fsr.read();
if( fsr.wasPressed() ){
counter = counter + 1
matrix.setTextColor( matrix.Color333(0,7,7) );
matrix.print( counter )
}
}
EDIT
// testshapes demo for Adafruit RGBmatrixPanel library.
// Demonstrates the drawing abilities of the RGBmatrixPanel library.
// For 32x32 RGB LED matrix:
// http://www.adafruit.com/products/607
// Written by Limor Fried/Ladyada & Phil Burgess/PaintYourDragon
// for Adafruit Industries.
// BSD license, all text above must be included in any redistribution.
#include <Adafruit_GFX.h> // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library
// If your 32x32 matrix has the SINGLE HEADER input,
// use this pinout:
#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
#define D A3
#define PULLUP true //use the AVR's internal pullup resistor
#define INVERT true //low level means fsr pressed
#define DEBOUNCE_TIME 50 //milliseconds
// If your matrix has the DOUBLE HEADER input, use:
//#define CLK 8 // MUST be on PORTB! (Use pin 11 on Mega)
//#define LAT 9
//#define OE 10
//#define A A3
//#define B A2
//#define C A1
//#define D A0
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);
void setup(){
Serial.begin(9600);
matrix.begin();
// draw a pixel in solid white
matrix.drawPixel(0, 0, matrix.Color333(7, 7, 7));
delay(500);
// fix the screen with green
matrix.fillRect(0, 0, 32, 32, matrix.Color333(0, 7, 0));
delay(500);
// draw a box in yellow
matrix.drawRect(0, 0, 32, 32, matrix.Color333(7, 7, 0));
delay(500);
// draw an 'X' in red
matrix.drawLine(0, 0, 31, 31, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 0, 31, matrix.Color333(7, 0, 0));
delay(500);
// draw a blue circle
matrix.drawCircle(10, 10, 10, matrix.Color333(0, 0, 7));
delay(500);
// fill a violet circle
matrix.fillCircle(21, 21, 10, matrix.Color333(7, 0, 7));
delay(500);
// fill the screen with 'black'
matrix.fillScreen(matrix.Color333(0, 0, 0));
// draw some text!
matrix.setCursor(1, 0); // start at top left, with one pixel of spacing
matrix.setTextSize(1); // size 1 == 8 pixels high
matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.println("FIST");
matrix.println(" BUMP");
// print each letter with a rainbow color
matrix.setTextColor(matrix.Color333(7,0,0));
matrix.print('C');
matrix.setTextColor(matrix.Color333(7,4,0));
matrix.print('O');
matrix.setTextColor(matrix.Color333(7,7,0));
matrix.print('U');
matrix.setTextColor(matrix.Color333(4,7,0));
matrix.print('N');
matrix.setTextColor(matrix.Color333(0,7,0));
matrix.println('T');
}
void loop(){
const int fsr_pin = A4; //connect fsr from this pin to ground
int read fsrAnalogPin = 4;
fsr_pin.read();
if( fsr_pin.wasPressed() ){
counter = counter + 1
matrix.setTextColor( matrix.Color333(0,7,7) );
matrix.print( counter )
}
}
I will also suggest following proper indentation. That will make your code readable. It would be also great if you revise your Arduino prog. concepts.
As soon as I set glEnable(GL_DEPTH_TEST) in the following code, nothing except for the clear color gets drawn on screen.
window.cpp
void Window::initializeGL() {
makeCurrent();
initializeOpenGLFunctions();
glClearColor(0.0f, 0.03f, 0.2f, 1.0f);
Shaders::initShaders();
glEnable(GL_DEPTH_TEST);
currentLevel.addTiles();
viewMatrix.setToIdentity();
viewMatrix.translate(0.0f, 0.0f, -8.0f);
viewMatrix.rotate(45.0f, -1.0f, 0.0f, 0.0f);
}
void Window::resizeGL(int width, int height) {
const float fov = 45.0f,
zNear = 0.0f,
zFar = 1000.0f;
projectionMatrix.setToIdentity();
projectionMatrix.perspective(fov, width / float(height), zNear, zFar);
}
void Window::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
currentLevel.setProjectionMatrix(projectionMatrix);
currentLevel.setViewMatrix(viewMatrix);
currentLevel.draw();
}
tile.cpp:
// Constructor with custom shader
Tile::Tile(QVector3D v1, QVector3D v2, QVector3D v3, QVector3D v4, QOpenGLShaderProgram* shaderProgram) :
vbo(QOpenGLBuffer::VertexBuffer),
cbo(QOpenGLBuffer::VertexBuffer),
ibo(QOpenGLBuffer::IndexBuffer) {
// Calculate surface normal & second set of vertices
QVector3D surfaceNormal = QVector3D::normal(v1, v2, v3);
QVector3D v1_n = v1 - surfaceNormal;
QVector3D v2_n = v2 - surfaceNormal;
QVector3D v3_n = v3 - surfaceNormal;
QVector3D v4_n = v4 - surfaceNormal;
// Set up rectangular mesh from given corner vectors
vertices = {
v1, v2, v3, v4,
v1_n, v2_n, v3_n, v4_n
};
colors = {
color1, color1, color2, color2,
color1, color1, color2, color2
};
indices = {
// Face 1
0, 1, 2,
2, 3, 0,
// Face 2
0, 4, 5,
5, 1, 0,
// Face 3
4, 5, 6,
6, 7, 4
};
this->shaderProgram = shaderProgram;
cacheShaderLocations();
createBuffers();
}
Tile::~Tile() {
vbo.destroy();
vao.destroy();
ibo.destroy();
}
// Cache Uniform Locations for shaders
void Tile::cacheShaderLocations() {
positionLocation = shaderProgram->attributeLocation("position");
colorLocation = shaderProgram->attributeLocation("color");
modelLocation = shaderProgram->uniformLocation("model");
viewLocation = shaderProgram->uniformLocation("view");
projectionLocation = shaderProgram->uniformLocation("projection");
}
// Create buffers
void Tile::createBuffers() {
// Vertex Buffer Object
vbo.create();
vbo.bind();
vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
vbo.allocate(vertices.constData(), vertices.size() * sizeof(QVector3D));
vbo.release();
// Color Buffer Object
cbo.create();
cbo.bind();
cbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
cbo.allocate(colors.constData(), colors.size() * sizeof(QVector3D));
cbo.release();
// Index Buffer Object
ibo.create();
ibo.bind();
ibo.setUsagePattern(QOpenGLBuffer::StaticDraw);
ibo.allocate(indices.constData(), indices.size() * sizeof(GLushort));
ibo.release();
// Vertex Array Object
vao.create();
// Setup buffer attributes
shaderProgram->bind();
vao.bind();
vbo.bind();
shaderProgram->enableAttributeArray(positionLocation);
shaderProgram->setAttributeBuffer(positionLocation, GL_FLOAT, 0, 3, 0);
cbo.bind();
shaderProgram->enableAttributeArray(colorLocation);
shaderProgram->setAttributeBuffer(colorLocation, GL_FLOAT, 0, 3, 0);
ibo.bind();
vao.release();
// Release buffers & shader program
vbo.release();
cbo.release();
ibo.release();
shaderProgram->release();
}
void Tile::draw() {
shaderProgram->bind();
// Send uniforms to shader
shaderProgram->setUniformValue(projectionLocation, projectionMatrix);
shaderProgram->setUniformValue(viewLocation, viewMatrix);
shaderProgram->setUniformValue(modelLocation, modelMatrix);
// Draw vertices
vao.bind();
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
vao.release();
shaderProgram->release();
}
As for the depth buffer itself, according to the Qt documentation it's enabled by default. In the main.cpp I set the surface format/context like this:
// Set OpenGL Version information
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(3,3);
I really have no clue why nothing gets drawn when I try to use depth testing so I would greatly appreciate any help.