Related
I am attempting to generate a ranged bar chart using System.Windows.Forms.DataVisualization.Charting.SeriesChartType.RangeBar. When I add the x axis as integers it renders correctly as shown below:
int[] x = { 0, 0, 0, 1, 1, 1 };
int[] y = { 10, 2, 35, 1, 10, 20 };
int[] y2 = { 35, 4, 36, 2, 15, 40 };
var xValue = x.ToList();
var yValue1 = y.ToList();
var yValue2 = y2.ToList();
chart2.Series[0].Points.DataBindXY(x, y, y2);
However, when I swap the x axis integers to strings the chart does not render as above:
string[] x = { "Test", "Test", "Test", "Test1", "Test1", "Test1" };
int[] y = { 10, 2, 35, 1, 10, 20 };
int[] y2 = { 35, 4, 36, 2, 15, 40 };
var xValue = x.ToList();
var yValue1 = y.ToList();
var yValue2 = y2.ToList();
chart2.Series[0].XValueType =
System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
chart2.Series[0].Points.DataBindXY(x, y, y2);
Is there an elegant workaround to using string values for the x-axis while maintaining int or DateTime values for the y axis? Thanks in advance for your help.
You can try it!
int[] tmpx = { 0, 0, 0, 1, 1, 1 };
string[] x = { "Test", "Test", "Test", "Test1", "Test1", "Test1" };
int[] y = { 10, 2, 35, 1, 10, 20 };
int[] y2 = { 35, 4, 36, 2, 15, 40 };
//var xValue = x.ToList();
//var yValue1 = y.ToList();
//var yValue2 = y2.ToList();
for (int i = 0; i<x.Length; i++)
{
int index = chart1.Series[0].Points.AddXY(tmpx[i], y[i], y2[i]);
chart1.Series[0].Points[index].AxisLabel = x[i];
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Point Lighting</title>
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin></script><script src="https://unpkg.com/#material-ui/core#4.11.0/umd/material-ui.production.min.js" crossorigin="anonymous"></script>
<style>
canvas {
width: 40vw;
height: 40vh;
background-color: lightpink;
}
#uiContainer {
top: 0;
width: 80%;
border: 2px solid blue;
background-color: lightblue;
padding: 10px;
float: left;
}
#ui {
background-color: coral;
transform: translate(0%, 0px);
display: block;
float: left;
}
</style>
<h3>
Drag slider to rotate
</h3>
</head>
<body>
<p>ok</p>
<canvas id="canvas" width="200" height="200"></canvas>
<div id="uiContainer">
<div id="ui">
</div>
</div>
<!-- vertex shader -->
<script id="3d-vertex-shader" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec3 a_normal;
uniform vec3 u_lightWorldPosition;
uniform mat4 u_world;
uniform mat4 u_worldViewProjection;
uniform mat4 u_worldInverseTranspose;
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
void main() {
// Multiply the position by the matrix.
gl_Position = u_worldViewProjection * a_position;
// orient the normals and pass to the fragment shader
// v_normal = mat3(u_worldInverseTranspose) * a_normal;
v_normal = mat3(u_world) * a_normal;
// compute the world position of the surfoace
vec3 surfaceWorldPosition = (u_world * a_position).xyz;
// compute the vector of the surface to the light
// and pass it to the fragment shader
v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;
}
</script>
<!-- fragment shader -->
<script id="3d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
// Passed in from the vertex shader.
varying vec3 v_normal;
varying vec3 v_surfaceToLight;
uniform vec4 u_color;
void main() {
// because v_normal is a varying it's interpolated
// so it will not be a unit vector. Normalizing it
// will make it a unit vector again
vec3 normal = normalize(v_normal);
vec3 surfaceToLightDirection = normalize(v_surfaceToLight);
float light = dot(normal, surfaceToLightDirection);
gl_FragColor = u_color;
// Lets multiply just the color portion (not the alpha)
// by the light
gl_FragColor.rgb *= light;
}
</script>
<script>
function RadToDegSlider(props) {
const {min, max, value, onChange} = props;
const [v, setV] = React.useState(radToDeg(value));
return (
<RangeSlider
min={min}
max={max}
value={v}
onChange={(e, v) => {
setV(v);
onChange(degToRad(v));
}}
/>
);
}
// Setup a ui.
const domContainer = document.querySelector('#ui');
ReactDOM.render(
<RadToDegSlider
value={getRotation()}
onChange={v => {
fRotationRadians = v;
drawScene();
}}
min={-360}
max={360} />, domContainer);
function getRotation() {
return fRotationRadians;
}
function updateRotation(value) {
fRotationRadians = value;
drawScene();
}
</script>
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
<script>
"use strict";
function main() {
// Get A WebGL context
/** #type {HTMLCanvasElement} */
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
var program = webglUtils.createProgramFromScripts(gl, ["3d-vertex-shader", "3d-fragment-shader"]);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
var normalLocation = gl.getAttribLocation(program, "a_normal");
// lookup uniforms
var worldViewProjectionLocation = gl.getUniformLocation(program, "u_worldViewProjection");
var worldInverseTransposeLocation = gl.getUniformLocation(program, "u_worldInverseTranspose");
var colorLocation = gl.getUniformLocation(program, "u_color");
var lightWorldPositionLocation = gl.getUniformLocation(program, "u_lightWorldPosition");
var worldLocation = gl.getUniformLocation(program, "u_world");
// Create a buffer to put positions in
var positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Put geometry data into buffer
setGeometry(gl);
// Create a buffer to put normals in
var normalBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = normalBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
// Put normals data into buffer
setNormals(gl);
function radToDeg(r) {
return r * 180 / Math.PI;
}
function degToRad(d) {
return d * Math.PI / 180;
}
var fieldOfViewRadians = degToRad(50);
var fRotationRadians = 0;
drawScene();
// Draw the scene.
function drawScene() {
// webglUtils.resizeCanvasToDisplaySize(gl.canvas);
// Tell WebGL how to convert from clip space to pixels
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// console.log(gl.canvas.width,gl.canvas.height);
// Clear the canvas AND the depth buffer.
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Turn on culling. By default backfacing triangles
// will be culled.
//gl.enable(gl.CULL_FACE);
// Enable the depth buffer
gl.enable(gl.DEPTH_TEST);
// Tell it to use our program (pair of shaders)
gl.useProgram(program);
// Turn on the position attribute
gl.enableVertexAttribArray(positionLocation);
// Bind the position buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 3; // 3 components per iteration
var type = gl.FLOAT; // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer( positionLocation, size, type, normalize, stride, offset);
// Turn on the normal attribute
gl.enableVertexAttribArray(normalLocation);
// Bind the normal buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
// Tell the attribute how to get data out of normalBuffer (ARRAY_BUFFER)
var size = 3; // 3 components per iteration
var type = gl.FLOAT; // the data is 32bit floating point values
var normalize = false; // normalize the data (convert from 0-255 to 0-1)
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
gl.vertexAttribPointer( normalLocation, size, type, normalize, stride, offset);
// Compute the projection matrix
var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
var zNear = 1;
var zFar = 2000;
var projectionMatrix = m4.perspective(fieldOfViewRadians, aspect, zNear, zFar);
// Compute the camera's matrix
var camera = [100, 150, 200];
var target = [0, 35, 0];
var up = [0, 1, 0];
var cameraMatrix = m4.lookAt(camera, target, up);
// Make a view matrix from the camera matrix.
var viewMatrix = m4.inverse(cameraMatrix);
// Compute a view projection matrix
var viewProjectionMatrix = m4.multiply(projectionMatrix, viewMatrix);
// Draw a F at the origin
var worldMatrix = m4.yRotation(fRotationRadians);
//console.log('stampa');
//console.log(worldMatrix);
// Multiply the matrices.
var worldViewProjectionMatrix = m4.multiply(viewProjectionMatrix, worldMatrix);
var worldInverseMatrix = m4.inverse(worldMatrix);
//console.log(worldInverseMatrix);
var worldInverseTransposeMatrix = m4.transpose(worldInverseMatrix);
//console.log(worldInverseTransposeMatrix);
// Set the matrices
gl.uniformMatrix4fv(worldViewProjectionLocation, false, worldViewProjectionMatrix);
gl.uniformMatrix4fv(worldInverseTransposeLocation, false, worldInverseTransposeMatrix);
gl.uniformMatrix4fv(worldLocation, false, worldMatrix);
// Set the color to use
gl.uniform4fv(colorLocation, [0.2, 1, 0.2, 1]); // green
// set the light position
gl.uniform3fv(lightWorldPositionLocation, [20, 30, 60]);
// Draw the geometry.
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 16 * 6;
gl.drawArrays(primitiveType, offset, count);
}
}
// Fill the buffer with the values that define a letter 'F'.
function setGeometry(gl) {
var positions = new Float32Array([
// left column front
0, 0, 0,
0, 150, 0,
30, 0, 0,
0, 150, 0,
30, 150, 0,
30, 0, 0,
// top rung front
30, 0, 0,
30, 30, 0,
100, 0, 0,
30, 30, 0,
100, 30, 0,
100, 0, 0,
// middle rung front
30, 60, 0,
30, 90, 0,
67, 60, 0,
30, 90, 0,
67, 90, 0,
67, 60, 0,
// left column back
0, 0, 30,
30, 0, 30,
0, 150, 30,
0, 150, 30,
30, 0, 30,
30, 150, 30,
// top rung back
30, 0, 30,
100, 0, 30,
30, 30, 30,
30, 30, 30,
100, 0, 30,
100, 30, 30,
// middle rung back
30, 60, 30,
67, 60, 30,
30, 90, 30,
30, 90, 30,
67, 60, 30,
67, 90, 30,
// top
0, 0, 0,
100, 0, 0,
100, 0, 30,
0, 0, 0,
100, 0, 30,
0, 0, 30,
// top rung right
100, 0, 0,
100, 30, 0,
100, 30, 30,
100, 0, 0,
100, 30, 30,
100, 0, 30,
// under top rung
30, 30, 0,
30, 30, 30,
100, 30, 30,
30, 30, 0,
100, 30, 30,
100, 30, 0,
// between top rung and middle
30, 30, 0,
30, 60, 30,
30, 30, 30,
30, 30, 0,
30, 60, 0,
30, 60, 30,
// top of middle rung
30, 60, 0,
67, 60, 30,
30, 60, 30,
30, 60, 0,
67, 60, 0,
67, 60, 30,
// right of middle rung
67, 60, 0,
67, 90, 30,
67, 60, 30,
67, 60, 0,
67, 90, 0,
67, 90, 30,
// bottom of middle rung.
30, 90, 0,
30, 90, 30,
67, 90, 30,
30, 90, 0,
67, 90, 30,
67, 90, 0,
// right of bottom
30, 90, 0,
30, 150, 30,
30, 90, 30,
30, 90, 0,
30, 150, 0,
30, 150, 30,
// bottom
0, 150, 0,
0, 150, 30,
30, 150, 30,
0, 150, 0,
30, 150, 30,
30, 150, 0,
// left side
0, 0, 0,
0, 0, 30,
0, 150, 30,
0, 0, 0,
0, 150, 30,
0, 150, 0]);
// Center the F around the origin and Flip it around. We do this because
// we're in 3D now with and +Y is up where as before when we started with 2D
// we had +Y as down.
// We could do by changing all the values above but I'm lazy.
// We could also do it with a matrix at draw time but you should
// never do stuff at draw time if you can do it at init time.
var matrix = m4.xRotation(Math.PI);
matrix = m4.translate(matrix, -50, -75, -15);
for (var ii = 0; ii < positions.length; ii += 3) {
var vector = m4.transformPoint(matrix, [positions[ii + 0], positions[ii + 1],
positions[ii + 2], 1]);
positions[ii + 0] = vector[0];
positions[ii + 1] = vector[1];
positions[ii + 2] = vector[2];
}
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
}
function setNormals(gl) {
var normals = new Float32Array([
// left column front
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
// top rung front
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
// middle rung front
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
// left column back
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
// top rung back
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
// middle rung back
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
0, 0, -1,
// top
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
// top rung right
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
// under top rung
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
// between top rung and middle
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
// top of middle rung
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
0, 1, 0,
// right of middle rung
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
// bottom of middle rung.
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
// right of bottom
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0,
// bottom
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
0, -1, 0,
// left side
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
-1, 0, 0,
-1, 0, 0]);
gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW);
}
main();
</script>
</body>
</html>
I have all the code in this html file and I import the libraries with cdn, but I can't see the slider in the web page. I'm new to react and webgl, and don't understand where the problem is. How can I do? Thank you all.
There are few issues in your code, I've created a working demo. https://codesandbox.io/s/eager-rgb-9h18u?file=/index.html
You have missed babel import
Missing type="text/babel" on script tag
Slider is the correct component name
I am trying to print a 2d array that has a maximum of 3 digit numbers that are aligned when printed. For example, with a simple printf, it looks like this:
[0, 232, 20, 96, 176, 0, 0]
[0, 0, 24, 0, 0, 176, 0]
[0, 0, 0, 0, 0, 0, 0]
I would like it to be printed with all the commas aligned along the columns with additional whitespace, like this:
[ 0, 232, 20, 96, 176, 0, 0]
[ 0, 0, 24, 0, 0, 176, 0]
[ 0, 0, 0, 0, 0, 0, 0]
How can I do this with printf?
You can use the width prefix to specify the minimum width for the printf conversions: printf("%4d", x); will print int variable x padded to the left with enough spaces to produce at least 4 characters.
If you know the maximum width of any number in the array, you can hardcode this number in the format string. Otherwise you can compute the required width and use %*d and pass an extra argument to specifying the computed width.
Here is a modified version:
#include <stdio.h>
int main(void) {
#define M 3
#define N 7
int a[M][N] = {
{ 0, 232, 20, 96, 176, 0, 0 },
{ 0, 0, 24, 0, 0, 176, 0 },
{ 0, 0, 0, 0, 0, 0, 0 },
};
int width = 0;
/* compute the required width */
for (size_t i = 0; i < M; i++) {
for (size_t j = 0; j < N; j++) {
int w = snprintf(NULL, 0, "%d", a[i][j]);
if (width < w) {
width = w;
}
}
}
/* print the arrays */
for (size_t i = 0; i < M; i++) {
printf("[");
for (size_t j = 0; j < N; j++) {
if (j != 0) printf(", ");
printf("%*d", width, a[i][j]);
}
printf("]\n");
}
return 0;
}
Output:
[ 0, 232, 20, 96, 176, 0, 0]
[ 0, 0, 24, 0, 0, 176, 0]
[ 0, 0, 0, 0, 0, 0, 0]
Here you are.
#include <stdio.h>
int main(void)
{
enum { M = 3, N = 7 };
int a[M][N] =
{
{ 0, 232, 20, 96, 176, 0, 0 },
{ 0, 0, 24, 0, 0, 176, 0 },
{ 0, 0, 0, 0, 0, 0, 0 }
};
int width = 4;
for ( size_t i = 0; i < M; i++ )
{
putchar( '[' );
for ( size_t j = 0; j < N; j++ )
{
if ( j != 0 ) putchar( ',' );
printf( "%*d", width, a[i][j] );
}
printf( "]\n" );
}
putchar( '\n' );
return 0;
}
The program output is
[ 0, 232, 20, 96, 176, 0, 0]
[ 0, 0, 24, 0, 0, 176, 0]
[ 0, 0, 0, 0, 0, 0, 0]
You can change the value of the variable width if you want for example to output larger values than values consisting from 3 digits. That is the output is enough flexible.
If you want to place the array output in a separate function then the corresponding function can look the following way provided that the compiler supports variable length arrays.
#include <stdio.h>
void format_output( size_t m, size_t n, int a[m][n], int width )
{
for ( size_t i = 0; i < m; i++ )
{
putchar( '[' );
for ( size_t j = 0; j < n; j++ )
{
if ( j != 0 ) putchar( ',' );
printf( "%*d", width, a[i][j] );
}
printf( "]\n" );
}
}
int main(void)
{
enum { M = 3, N = 7 };
int a[M][N] =
{
{ 0, 232, 20, 96, 176, 0, 0 },
{ 0, 0, 24, 0, 0, 176, 0 },
{ 0, 0, 0, 0, 0, 0, 0 }
};
int width = 4;
format_output( M, N, a, width );
putchar( '\n' );
return 0;
}
The program output is the same as shown above that is
[ 0, 232, 20, 96, 176, 0, 0]
[ 0, 0, 24, 0, 0, 176, 0]
[ 0, 0, 0, 0, 0, 0, 0]
use this format of printf printf("%4d", arr[i][j]);
int main()
{
int arr[3][7] = { {0, 232, 20, 96, 176, 0, 0}
,{0, 0, 24, 0, 0, 176, 0}
,{0, 0, 0, 0, 0, 0, 0} };
for (int i = 0; i < 3; i++)
{
printf("[");
for (int j = 0; j < 7; j++)
{
if (j < 6)
printf("%4d,", arr[i][j]);
if (j == 6)
printf("%4d", arr[i][j]);
}
printf("]");
printf("\n");
}
}
PS:amount of space can be changed as needed ,with changing "%4d".
I receive data from an external device in decimal values, that I need to convert in ascii and then push it in a list
data example:
#onData: 1,3,200,
78,69,84,71,69,65,82,45,71,117,101,115,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70,114,105,103,111,109,97,116,45,49,50,51,52,53,54,55,56,45,87,73,70,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77,73,67,82,79,45,83,89,83,84,69,77,83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77,73,67,82,79,45,83,89,83,84,69,77,83,45,71,85,69,83,84,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
77,73,67,82,79,45,83,89,83,84,69,77,83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,123
The first 3 elements of #onData need to be ignored and the last 2 elements as well.
In ascii it would be:
NETGEAR-Guest
Frigomat-12345678-WIFI
MICRO-SYSTEMS
MICRO-SYSTEMS-GUEST
MICRO-SYSTEMS
I have a method to convert:
arrayBuffer2str(buf) {
var str = "";
var ui8 = new Uint8Array(buf);
for (var i = 0; i < ui8.length; i++) {
str = str + String.fromCharCode(ui8[i]);
}
return str;
}
I would need to get rid of the zeros and then push it in an array of strings:
this.wifiNetworks.push("Network-1");
Thank you
If you want to extract the buffer between two zeros and isolate the significant response, try this
let prevVal;
let phrase= [];
for (let i=0; i<array.length; i++) {
let val = array[i];
if (val == 0 && prevVal != 0) {
// end of response
process(phrase);
}
if (prevVal == 0 && val != 0) {
// start new response
phrase= [];
}
phrase.push(val);
prevVal = val;
}
function process(phrase) {
// TODO Process your phrase here and remove the inner zeros
}
Also, consider removing your zeros using the .filter function
Try this,
Assuming that we are getting the input as an array.
const inputArray = [1, 3, 200,
78, 69, 84, 71, 69, 65, 82, 45, 71, 117, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70, 114, 105, 103, 111, 109, 97, 116, 45, 49, 50, 51, 52, 53, 54, 55, 56, 45, 87, 73, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77, 73, 67, 82, 79, 45, 83, 89, 83, 84, 69, 77, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77, 73, 67, 82, 79, 45, 83, 89, 83, 84, 69, 77, 83, 45, 71, 85, 69, 83, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77, 73, 67, 82, 79, 45, 83, 89, 83, 84, 69, 77, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 123];
const resultArray = [];
let stringIndex = 0;
for (i = 3; i <= inputArray.length - 3; i++) {
if (inputArray[i] !== 0) {
resultArray[stringIndex] = resultArray[stringIndex]
? resultArray[stringIndex].concat(String.fromCharCode(inputArray[i]))
: ''.concat(String.fromCharCode(inputArray[i]));
} else if (inputArray[i - 1] !== 0) {
stringIndex = stringIndex + 1
}
}
console.log(resultArray);
// Add code to push the result to server,
The output would be
[ 'NETGEAR-Guest', 'Frigomat-12345678-WIFI', 'MICRO-SYSTEMS',
'MICRO-SYSTEMS-GUEST', 'MICRO-SYSTEMS' ]
I have a piece of code that runs on an embedded system. Its job is to convert some ASCII characters into proprietary data. The data is stored in a multi-dimensional array and what appears to be the problem, although I am unable to confirm this with the hardware debugger, is that the bit variable is staying at value 2. This code works the first two times it is run, but on the third run it breaks and returns starts sending wrong data through the UART interface. I though maybe someone else analyzing this might be able to see what I'm missing. This is C99 which I am not too familiar with. Bleow is the entire function, but I think the problem is with the for statement?? Any help would be greatly appreciated!
void simple_uart_putstring(uint8_t *str, uint16_t length)
{
//send data bits
uint_fast8_t index = 0;
uint8_t ch = str[index++];
uint_fast8_t bitCount = 0;
int index2 = 0;
int bit = 0;
if (length > 1)
{
while (length >= index)
{
if (bitCount < 2)
{
if (length < 10)
{
//send sync bits
simple_uart_put(254);
simple_uart_put(223);
bitCount = 2;
} else {
//send sync bits and add scrolling
simple_uart_put(254);
simple_uart_put(222);
bitCount = 2;
}
}
//send each bit for each letter in the string
for (uint_fast8_t i = 0; i < 5; i++)
{
index2 = (int)ch;
bit = (int)i;
simple_uart_put(matrix[index2 - 32][bit]);
bitCount++;
}
ch = str[index++];
}
//the main controller is expecting 150 bits total to continue to send bit until 150
while (bitCount <= 150)
{
simple_uart_put(0);
bitCount++;
if(bitCount >= 150)
{
bitCount = 0;
break;
}
}
bitCount = 0;
}
}
And here is a sample of the array:
const uint8_t matrix[59][5] =
{
{ 0, 0, 0, 0, 0}, //space
{ 0, 125, 0, 0, 0}, //!
{ 0, 112, 0, 112, 0}, //"
{127, 127, 127, 127, 127 }, //#
{ 18, 42, 107, 36, 0}, //$
{ 50, 52, 22, 38, 0}, //%
{ 38, 89, 57, 6, 9}, //&
{ 64, 48, 0, 0, 0}, //'
{ 0, 0, 62, 65, 0}, //(
{ 0, 65, 62, 0, 0}, //)
{ 20, 8, 62, 8, 20}, //*
{ 0, 8, 28, 8, 0}, //+
{ 1, 6, 0, 0, 0}, //,
{ 0, 8, 8, 8, 0}, //-
{ 3, 3, 0, 0, 0}, //.
{ 2, 4, 8, 16, 32}, //
{ 62, 69, 73, 62, 0}, //0
{ 1, 33, 127, 1, 0}, //1
{ 35, 67, 69, 49, 0}, //2
{ 34, 73, 73, 54, 0}, //3
{ 12, 20, 36, 127, 0}, //4
{ 114, 81, 81, 78, 0}, //5
{ 30, 41, 73, 6, 0}, //6
{ 64, 71, 72, 112, 0}, //7
{ 54, 73, 73, 54, 0}, //8
{ 48, 73, 74, 60, 0}, //9
{ 0, 54, 54, 0, 0}, //:
{ 0, 1, 54, 0, 0}, //;
{ 0, 8, 20, 34, 0}, //<
{ 0, 20, 20, 20, 0}, //=
{ 0, 34, 20, 8, 0}, //>
{ 32, 64, 69, 72, 48}, //?
{ 62, 65, 93, 93, 112}, //#
{ 63, 72, 72, 63, 0 }, //a
{ 127, 73, 73, 54, 0 }, //b
{ 62, 65, 65, 34, 0}, //c
{ 127, 65, 34, 28, 0 }, //d
{ 127, 73, 73, 65, 0}, //e
{ 127, 72, 72, 64, 0}, //f
{ 62, 65, 73, 47, 0}, //g
{ 127, 8, 8, 127, 0}, //h
{ 0, 65, 127, 65, 0},//i
{ 6, 65, 126, 64, 0}, //j
{ 127, 8, 20, 99, 0}, //k
{ 127, 1, 1, 1, 0}, //l
{ 127, 32, 24, 32, 127}, //m
{ 127, 16, 8, 127, 0}, //n
{ 62, 65, 65, 62, 0}, //o
{ 127, 72, 72, 48, 0}, //p
{ 60, 70, 66, 61, 0}, //q
{ 127, 76, 74, 49, 0}, //r
{ 50, 73, 73, 38, 0}, //s
{ 0, 64, 127, 64, 0}, //t
{ 126, 1, 1, 126, 0},
{ 127, 1, 2, 124, 0},
{ 126, 1, 6, 1, 126},
{ 99, 28, 28, 99, 0},
{ 112, 8, 8, 127, 0},
{ 71, 73, 81, 97, 0}};
And the uart send method:
void simple_uart_put(uint8_t cr)
{
NRF_UART0->TXD = (uint8_t)cr;
while (NRF_UART0->EVENTS_TXDRDY!=1)
{
// Wait for TXD data to be sent
}
NRF_UART0->EVENTS_TXDRDY=0;
}
An example of this working would be if the input string is "AB" and the length = 2;
It should send the following bytes via UART:
{254, 223, 63, 72, 72, 63, 0, 127, 73, 73, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, etc....}
The first two bytes are sync bytes, the next five come from the array matrix[33][0 to 4] because ASCII 'A' = 65 and 65-32 = 33. Then the next five come from ASCII 'B' = 66 and 66 - 32 = 34 so they are sent from matrix[34][0 to 4]. Then the next n = 150 - bitNumber are sent as 0 because the main controller is expecting 150 bytes always.
See edit at bottom
Without having definitions for all functions, I cannot completely analyze this, however there are a couple of suspicious things:
1) this declaration is odd:
uint_fast8_t index = 0;
uint8_t ch = str[index++]; //always sets ch to first character of input "str" then increments index.
NOTE: corrected comment on previous line.
2) although the comment indicates "each bit for each letter in the string" it only handle 5:
for (uint_fast8_t i = 0; i < 5; i++){...} //what if lenth of input is less than 5?
Suggest changing to:
for (uint_fast8_t i = 0; i < length; i++){...} //used second argument "length"
3) Finally, it seems that null terminating the string should follow the for loop, but: (see comments in line) (Also, input arguments used were "abc", 4)
for (uint_fast8_t i = 0; i < 5; i++)
{
index2 = (int)ch; //ch inits to first char in str, and indexes through
bit = (int)i;
//simple_uart_put(matrix[index2 - 32][bit]);
bitCount++;
}
ch = str[index++]; //terminates in second character of input "b' in this case
//I think this should null terminate with '\0' if it is to be treated as a C string,
//but because, as you say, this is "proprietary", I am not sure.
EDIT
I think the problem may be that you have declared the variable matrix with what looks like sufficient room, but only initialized it with three rows of data:
const uint8_t matrix[59][5] =
{
{ 0, 0, 0, 0, 0}, //space
{ 0, 125, 0, 0, 0}, //!
{ 0, 112, 0, 112, 0}, //"
}; //have only initialized matrix[0], matrix[1] and matrix[2]
The remaining 53 rows of data, although owned by you, have not been initialized that I can see. So, when you say:
the next five come from the array matrix[33][0 to 4] because ASCII 'A' = 65 and 65-32 = 33. Then the next five come from ASCII 'B' = 66 and 66 - 32 = 34 so they are sent from matrix[34][0 to 4]
That suggests what ever random number happens to be occupying those uninitialized memory locations, are what is being written out in the line:
simple_uart_put(matrix[index2 - 32][bit]);
EDIT 2 (See comment to explain)
Here is my main(), and commented simple_uart_putstring():
int main()
{
uint8_t *str;
int len=3;
str = malloc(3); //extra char for terminating null byte
strcpy(str, "AB");
simple_uart_putstring(str, 2);
free(str);
}
void simple_uart_putstring(uint8_t *str, uint16_t length)
{
//send data bits
uint_fast8_t index = 0;
uint8_t ch = str[index++]; //ch inits to first char in str, and indexes through
uint_fast8_t bitCount = 0;
int index2 = 0;
int bit = 0;
if (length > 1)
{
while (length >= index)
{
if (bitCount < 2)
{
if (length < 10)
{
//send sync bits
//simple_uart_put(254);
//simple_uart_put(223);
bitCount = 2;
} else {
//send sync bits and add scrolling
//simple_uart_put(254);
//simple_uart_put(222);
bitCount = 2;
}
}
//send each bit for each letter in the string
for (uint_fast8_t i = 0; i < 5; i++)
{
index2 = (int)ch; //
bit = (int)i;
/*simple_uart_put(*/matrix[index2 - 32][bit];//);break here to view "matrix[index2 - 32][bit]"
bitCount++;
}
ch = str[index++]; //
}
//the main controller is expecting 150 bits total to continue to send bit until 150
while (bitCount <= 150)
{
//simple_uart_put(0);
bitCount++;
if(bitCount >= 150)
{
bitCount = 0;
break;
}
}
bitCount = 0;
}
}