完整代码:Pastebin
启用了注释的完整代码(Google云端硬盘):SerialGrapherV0.9
正在执行的代码位于底部附近。
运行图形代码的youTube示例:Grapher
背景:我的目标是编写一个库,以允许调用方Arduino通过串行驱动被调用方Arduino,并在SSD1306 I2C显示器上打印主定义图或多个图(无SPI版本可测试)。图形代码已完成。当前,我可以有4个可以同步或异步更新的图,没有消隐,只写了需要更新的部分。
两个arduino当前都运行相同的草图,并通过接地的pullup_input确定其角色,但是在更高版本中,草图将使用带有#defined布尔值的if语句进行编译,以大大节省调用方arduino的程序空间。 >
到目前为止: 实际的图形工作正常,并且只要graphAdd(graphNumber,newVal);就会更新图形。叫做。 每个图的xpos,ypos,xlength和ylength可以在调用方定义如下:
#define masterGraphNum 4 //Set this to the number of Graphs you want.
graphStruct graph[masterGraphNum] = { //Each set of brackets is an instance of a graph, one for each specified in graphNum, set the array number on the receiver to the max number of graphs you can use.
//Graph 1 //Usage: {LeftX, TopY, width, height}
{0, 0, 31, 32},
//Graph 2
{32, 0, 31, 32},
//Graph 3
{64, 0, 31, 32},
//Graph 4
{96, 0, 31, 32},
};
当前,我正在尝试使用delete[] (graph);
,然后使用graphStruct *graph = new graphStruct[incomingGraphNum];
,其中,incomingGraphNum是由调用方发送并由被调用方接收的int,这似乎起初是可行的,但是经过一小段绘图之后大约15秒后,arduino崩溃并重新启动。
流量:
我的问题是现在从函数内部实例化一个可全局访问的结构数组,因为我不想将图的数量预先编码到被调用方中,也不需要在内部分配缓冲区数组的大小。结构。
要使函数起作用,graph []需要全局声明。我想在被调用方设置期间在函数内全局声明graph [图形数],因为我想将其作为我未来项目的即插即用诊断工具。
后续步骤: 设置数据包以发送图形数据。不太难,本质上是发送两个整数,例如(graph#,graphData) 添加图表“标题”(例如“ ACC”或“光强度”)
已实施:
答案 0 :(得分:0)
一些可能有用的想法。
显示为128像素,因此您需要的缓冲区不大于该像素。我建议您将其设置为单个全局缓冲区(而不是每个结构都有其自己的缓冲区)。无论您有多少张图,都无需使用new/delete
调整大小。
uint8_t global_graph_buffer[128];
请注意,我已将其从int
更改为byte
。显示屏的高度仅为30或40像素(?),因此无需存储任何更大的数字。只需在端口上输入时按比例缩小值即可。
graph_buffer[x] = map(incoming_data, 0, max_input, 0, height_of_graph);
请参阅Arduino map()
函数。
接下来,您是否真的需要图形的y_pos和高度?您计划有多于1行的图形吗?如果不是,请摆脱那些struct成员。同样,您也可以摆脱x_pos和width字段。这些可以根据索引进行计算。
struct graphStruct {
uint8_t gx; // Removed
uint8_t gy; // Removed
uint8_t gw; // Removed
uint8_t gh; // Removed
int gVal; // What is this for?
//int graphBuffer[graphBufferSize]; This is gone
uint8_t start_index; // First index in the global array
uint8_t end_index; // Last index
bool isReady; // What is this for?
};
要计算x_pos和宽度:
x_pos = start_index
width = end_index - start_index
要处理传入数据,请仅移动给定图的缓冲区的一部分并添加值:
int incoming_data = some_value_from_serial;
// Shift
for (byte i = graph[graphNumber].start_index+1; i < graph[graphNumber].end_index; i++) {
global_graph_buffer[i] = global_graph_buffer[i-1]
}
// Store
global_graph_buffer[i] = map(incoming_data, 0, graphMax, 0, 128);
最后,您需要考虑:一次可以实际显示多少个图形?设置最大值,并在开始时仅创建那么多结构。如我建议的那样,如果使用全局缓冲区,则可以多次重用结构(而不必使用new/delete
)。只需更改start_index
和end_index
字段即可。
不确定这是否有帮助,但是也许您可以从中获得一些想法。