Metaclass conflicts with a static method in c++ python extension - cpython

I am currently writing a python extension which contains a number of classes. I have encountered an unexpected behavior when compiling my extension against python 3.8 (it works fine in python 2.7). When my custom type definition uses a metaclass and provides a static method(s), such static method becomes difficult to call. Calling simply Foo.bar() causes a TypeError: 'staticmethod' object is not callable exception. I have produced a minimal example which reproduces that behavior in python 3.8:
#include <Python.h>
static PyModuleDef foomodule = {
PyModuleDef_HEAD_INIT,
"foo",
"Foo module",
-1, 0, 0, 0, 0
};
struct foo_FooObject {
PyObject_HEAD
};
static PyObject* foo_Foo_bar( PyObject *self, PyObject *args )
{
return self;
}
static PyMethodDef fooMethods[] = {
{ "bar", foo_Foo_bar, METH_STATIC | METH_VARARGS, "Foo.bar()" },
{ NULL, NULL, 0, NULL }
};
static PyTypeObject fooMetaType = {
PyVarObject_HEAD_INIT( &PyType_Type, 0 )
"Foometa",
sizeof(PyTypeObject),
0,
0, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
0, // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
0, // tp_getset
&PyType_Type, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
0, // tp_new
0, // tp_free
0, // tp_is_gc
0, // tp_bases
0, // tp_mro
0, // tp_cache
0, // tp_subclasses
0 // tp_weaklist
, 0 // tp_del
, 0 // tp_version_tag
, 0 // tp_finalize
};
static PyTypeObject foo_FooType = {
PyVarObject_HEAD_INIT(&fooMetaType, 0)
"foo.Foo", /* tp_name */
sizeof(foo_FooObject), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"foo.Foo object", /* tp_doc */
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
0, // tp_new
0, // tp_free
0, // tp_is_gc
0, // tp_bases
0, // tp_mro
0, // tp_cache
0, // tp_subclasses
0 // tp_weaklist
, 0 // tp_del
, 0 // tp_version_tag
, 0 // tp_finalize
};
PyMODINIT_FUNC PyInit_foo()
{
PyObject* foo = PyModule_Create( &foomodule );
if ( foo == NULL ) {
return NULL;
}
if ( PyType_Ready( &fooMetaType ) < 0 ) {
return NULL;
}
foo_FooType.tp_methods = fooMethods;
if ( PyType_Ready( &foo_FooType ) < 0 ) {
return NULL;
}
Py_INCREF( &foo_FooType );
PyModule_AddObject( foo, "Foo", (PyObject *)&foo_FooType );
return foo;
}
After compiling the extension and importing it, I would expect to be able
to say:
from foo import Foo
Foo.bar()
It works fine if I do not use metaclass, (ie.replace the &fooMetaType with NULL in the foo_FooType definition). Am I doing something wrong here? Can I even combine metaclasses with static methods, or is this not possible for some reason?

Related

python c api, how can I add function to class which defined in c layer

I defined a type spam.Foo follow Defining New Types.
Which like this.
PyObject *m;
m = Py_InitModule(MODULE_NAME, Spam_methods);
int rst = PyModule_AddObject(m, "Foo", (PyObject *)&FooPyType);
if (rst == -1) {
throw std::runtime_error("PyModule_AddObject(Foo) failed");
}
And the Foo PyTypeObject is like this:
PyTypeObject FooPyType = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"spam.Foo",
sizeof(Foo),
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
reinterpret_cast<reprfunc>(FooType_str),
0,
0,
0,
Py_TPFLAGS_DEFAULT,
"The spam Foo",
0,
0,
0,
0,
0,
0,
FooType_methods,
nullptr,
FooType_getSet
};
Now I want create a new function in python code:
from spam import Foo
setattr(Foo, "bar", lambda self: "Hello from bar")
But it throw an error: can't set attributes of built-in/extension type 'spam.Foo'.
How can I do this.

How to establish connection with kafka server in Rust

I'm trying to establish connection with kafka server without third party libraries in Rust.
This is the description of kafka server TCP protocol
This is my code:
fn connect() -> Result<(), std::io::Error> {
let stream = TcpStream::connect("localhost:9092").expect("Could not connect");
let mut input_stream = stream.try_clone().unwrap();
input_stream.set_read_timeout(Some(Duration::new(5, 0)));
input_stream.set_write_timeout(Some(Duration::new(5, 0)));
/// HERE IS MY PROBLEM. I DON'T KNOW HOW TO ENCODE KAFKA MESSAGE
let mut data = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
/// api key 0, 0, 0, 0, 0, 0
/// request_api_version 0, 0, 0, 0, 0, 0
/// correlation_id 0, 0, 0, 0, 0, 0,
let mut buffer: Vec<u8> = Vec::with_capacity(1400);
buffer.extend_from_slice(&[0; 100]);
input_stream.write(&mut data)?;
match input_stream.read(&mut buffer) {
Ok(b) => {
println!("read ok - {:?}", String::from_utf8_lossy(&buffer));
}
Err(e) => println!("Error {}", e),
}
Ok(())
}
fn main() {
connect();
}
How to encode this kafka message to byte array ?
Variable data should be an array of bytes
Naive code for creating kafka message of next interface
request_api_key => INT16
request_api_version => INT16
correlation_id => INT32
const int16 = (prevBuffer: Buffer, value: number) => {
const newBuffer = Buffer.alloc(2)
newBuffer.writeInt16BE(value)
return Buffer.concat([prevBuffer, newBuffer]);
}
const int32 = (prevBuffer: Buffer, value: number) => {
const newBuffer = Buffer.alloc(4)
newBuffer.writeInt32BE(value)
return Buffer.concat([prevBuffer, newBuffer]);
}
const payload = int31(int16(int16(Buffer.alloc(0), 3), 0),1);
The code is shamelessly taken from kafkajs

What is difference Qt.matrix4x4 and QMatrix4x4?

I am learning the Qt 3D module. I found the Qt.matrix4x4 provide different API than QMatrix4x4 in C++ side (by using F1 check the API doc).
look likes Qt.matrix4x4 don't have such scale or rotation operations. even not in autocomplete.
BUT! these functions do exist and work!
var m = Qt.matrix4x4(1, 0, 0, -0.5, 0, 1, 0, 0, 0, 0, 1, 0.5, 0, 0, 0, 1)
m.scale(2)
console.log(m)
// qml: QMatrix4x4(2, 0, 0, -0.5, 0, 2, 0, 0, 0, 0, 2, 0.5, 0, 0, 0, 1)
// the type shows QMatrix4x4
https://doc.qt.io/qt-5/qmatrix4x4.html vs https://doc.qt.io/qt-5/qml-matrix4x4.html
I understand what these is, But why the API show different in API doc and autocomplete?
It is interesting to note that in Qt6 the documentation appears different than Qt5. In Qt6 we see clearly there are methods for constructing the matrix4x4 basic type from a vector and for multiplying them with vectors.
// translate(vector3d)
var m = Qt.matrix4x4();
m.translate(Qt.vector3d(1,2,3));
console.log(m.toString());
// QMatrix4x4(1, 0, 0, 1, 0, 1, 0, 2, 0, 0, 1, 3, 0, 0, 0, 1)
// matrix multiplication
var m = Qt.matrix4x4();
m.translate(Qt.vector3d(1,2,3));
console.log(m.toString());
// QMatrix4x4(1, 0, 0, 1, 0, 1, 0, 2, 0, 0, 1, 3, 0, 0, 0, 1)
// applying a matrix to a vector
var a = Qt.matrix4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
var b = Qt.vector3d(5,6,7);
var c = a.times(b);
console.log(c.toString()); // QVector3D(0.155556, 0.437037, 0.718518)
Note I tried all of the above in Qt5.15.6 but it doesn't work. So it appears that support for this type really kicks in at Qt6.
For further information see: https://doc.qt.io/qt-6/qml-matrix4x4.html

Endpoint returns presumably cloud config

I have this simple controller
#RestController
#RequestMapping("/metrics")
public class MetricsController {
#GetMapping
#ApiOperation("Get metrics by source")
public ResponseEntity<List<Metric>> getMetricBySource(#RequestParam String source) {
if (source.equalsIgnoreCase("recordings")) {
return new ResponseEntity<>(MetricsConstants.RECORDINGS_METRICS, HttpStatus.OK);
} else if (source.equalsIgnoreCase("advertisers")) {
return new ResponseEntity<>(MetricsConstants.ADVERTISERS_METRICS, HttpStatus.OK);
} else if (source.equalsIgnoreCase("publishers")) {
return new ResponseEntity<>(MetricsConstants.PUBLISHERS_METRICS, HttpStatus.OK);
} else if (source.equalsIgnoreCase("partners")) {
return new ResponseEntity<>(MetricsConstants.PARTNERS_METRICS, HttpStatus.OK);
} else if (source.equalsIgnoreCase("products")) {
return new ResponseEntity<>(MetricsConstants.PRODUCTS_METRICS, HttpStatus.OK);
} else if (source.equalsIgnoreCase("regular-users")) {
return new ResponseEntity<>(MetricsConstants.REGULAR_USERS_METRICS, HttpStatus.OK);
}
return null;
}
}
Now, when I'm trying to access the endpoint via
localhost:8099/metrics?source=advertisers
I'm getting the following response
{
"mem": 947258,
"mem.free": 367038,
"processors": 4,
"instance.uptime": 540532,
"uptime": 556754,
"systemload.average": -1,
"heap.committed": 854016,
"heap.init": 260096,
"heap.used": 486977,
"heap": 3699200,
"nonheap.committed": 95312,
"nonheap.init": 2496,
"nonheap.used": 93242,
"nonheap": 0,
"threads.peak": 61,
"threads.daemon": 37,
"threads.totalStarted": 128,
"threads": 53,
"classes": 13916,
"classes.loaded": 13916,
"classes.unloaded": 0,
"gc.ps_scavenge.count": 13,
"gc.ps_scavenge.time": 150,
"gc.ps_marksweep.count": 3,
"gc.ps_marksweep.time": 341,
"counter.servo.eurekaclient.transport.request": 0,
"counter.servo.eurekaclient.transport.connectionerrors": 0,
"counter.servo.timeouts": 0,
"counter.servo.rejectedexecutions": 0,
"counter.servo.throwables": 0,
"gauge.servo.threadpoolused": 0,
"gauge.servo.response.metrics": 6,
"normalized.servo.rest.totaltime": 0,
"normalized.servo.rest.count": 0,
"gauge.servo.rest.min": 0,
"gauge.servo.rest.max": 0,
"gauge.servo.eurekaclient.registration.lastheartbeatsec_00030": 0,
"counter.servo.discoveryclient-httpclient_reuse": 10,
"counter.servo.discoveryclient-httpclient_createnew": 26,
"counter.servo.discoveryclient-httpclient_request": 36,
"counter.servo.discoveryclient-httpclient_release": 36,
"counter.servo.discoveryclient-httpclient_delete": 24,
"normalized.servo.discoveryclient-httpclient_requestconnectiontimer.totaltime":
0.005046033333333333,
"normalized.servo.discoveryclient-httpclient_requestconnectiontimer.count":
0.06666666666666667,
"gauge.servo.discoveryclient-httpclient_requestconnectiontimer.min":
0.017749,
"gauge.servo.discoveryclient-httpclient_requestconnectiontimer.max":
0.12356299999999999,
"normalized.servo.discoveryclient-httpclient_createconnectiontimer.totaltime":
0.0012743166666666665,
"normalized.servo.discoveryclient-httpclient_createconnectiontimer.count":
0.05,
"gauge.servo.discoveryclient-httpclient_createconnectiontimer.min":
0.012288,
"gauge.servo.discoveryclient-httpclient_createconnectiontimer.max":
0.034475,
"gauge.servo.connectioncount": 2,
"normalized.servo.eurekaclient.transport.latency.totaltime": 0,
"normalized.servo.eurekaclient.transport.latency.count": 0,
"gauge.servo.eurekaclient.transport.latency.min": 0,
"gauge.servo.eurekaclient.transport.latency.max": 0,
"gauge.servo.response.star-star.favicon.ico": 42,
"gauge.servo.eurekaclient.registry.lastupdatesec_00240": 0,
"gauge.servo.eurekaclient.registration.lastheartbeatsec_00015": 1,
"gauge.servo.response.webjars.star-star": 5,
"gauge.servo.eurekaclient.resolver.endpointssize": 1,
"gauge.servo.eurekaclient.resolver.lastloadtimestamp": 233376,
"gauge.servo.eurekaclient.registration.lastheartbeatsec_00240": 0,
"gauge.servo.eurekaclient.transport.quarantinesize": 0,
"gauge.servo.eurekaclient.registry.lastupdatesec_00030": 0,
"gauge.servo.response.v2.api-docs": 126,
"gauge.servo.eurekaclient.registration.lastheartbeatsec_00480": 0,
"gauge.servo.eurekaclient.registry.lastupdatesec_00480": 0,
"gauge.servo.response.star-star": 13,
"gauge.servo.response.swagger-resources.configuration.ui": 19,
"normalized.servo.eureka-connection-cleaner-time.totaltime": 0.0009386666666666665,
"normalized.servo.eureka-connection-cleaner-time.count": 0.03333333333333333,
"gauge.servo.eureka-connection-cleaner-time.min": 0.021162,
"gauge.servo.eureka-connection-cleaner-time.max": 0.035158,
"counter.servo.eureka-connection-cleaner-failure": 0,
"gauge.servo.eurekaclient.transport.currentsessionduration": 533378,
"gauge.servo.eurekaclient.registration.lastheartbeatsec_00120": 0,
"gauge.servo.eurekaclient.registry.lastupdatesec_00015": 1,
"gauge.servo.response.swagger-resources.configuration.security": 4,
"gauge.servo.eurekaclient.registry.lastupdatesec_00120": 0,
"gauge.servo.response.info": 35,
"gauge.servo.eurekaclient.registration.lastheartbeatsec_00060": 0,
"gauge.servo.eurekaclient.registry.lastupdatesec_00060": 0,
"counter.servo.discoveryclient_reconcilehashcodemismatch": 0,
"normalized.servo.discoveryclient_fetchregistry.totaltime": 0.29706815000000003,
"normalized.servo.discoveryclient_fetchregistry.count": 0.03333333333333333,
"gauge.servo.discoveryclient_fetchregistry.min": 4.337664999999999,
"gauge.servo.discoveryclient_fetchregistry.max": 13.486424,
"counter.servo.discoveryclient_reregister": 0,
"gauge.servo.eurekaclient.registry.localregistrysize": 5,
"gauge.servo.eurekaclient.registry.lastsuccessfulregistryfetchtimeperiod":
22920,
"gauge.servo.eurekaclient.registration.lastsuccessfulheartbeattimeperiod":
22926,
"gauge.servo.response.swagger-resources": 5,
"integration.channel.errorChannel.errorRate.mean": 0,
"integration.channel.errorChannel.errorRate.max": 0,
"integration.channel.errorChannel.errorRate.min": 0,
"integration.channel.errorChannel.errorRate.stdev": 0,
"integration.channel.errorChannel.errorRate.count": 0,
"integration.channel.errorChannel.sendCount": 0,
"integration.channel.errorChannel.sendRate.mean": 0,
"integration.channel.errorChannel.sendRate.max": 0,
"integration.channel.errorChannel.sendRate.min": 0,
"integration.channel.errorChannel.sendRate.stdev": 0,
"integration.channel.errorChannel.sendRate.count": 0,
"integration.channel.springCloudBusInput.errorRate.mean": 0,
"integration.channel.springCloudBusInput.errorRate.max": 0,
"integration.channel.springCloudBusInput.errorRate.min": 0,
"integration.channel.springCloudBusInput.errorRate.stdev": 0,
"integration.channel.springCloudBusInput.errorRate.count": 0,
"integration.channel.springCloudBusInput.sendCount": 0,
"integration.channel.springCloudBusInput.sendRate.mean": 0,
"integration.channel.springCloudBusInput.sendRate.max": 0,
"integration.channel.springCloudBusInput.sendRate.min": 0,
"integration.channel.springCloudBusInput.sendRate.stdev": 0,
"integration.channel.springCloudBusInput.sendRate.count": 0,
"integration.channel.hystrixStreamOutput.errorRate.mean": 0,
"integration.channel.hystrixStreamOutput.errorRate.max": 0,
"integration.channel.hystrixStreamOutput.errorRate.min": 0,
"integration.channel.hystrixStreamOutput.errorRate.stdev": 0,
"integration.channel.hystrixStreamOutput.errorRate.count": 0,
"integration.channel.hystrixStreamOutput.sendCount": 0,
"integration.channel.hystrixStreamOutput.sendRate.mean": 0,
"integration.channel.hystrixStreamOutput.sendRate.max": 0,
"integration.channel.hystrixStreamOutput.sendRate.min": 0,
"integration.channel.hystrixStreamOutput.sendRate.stdev": 0,
"integration.channel.hystrixStreamOutput.sendRate.count": 0,
"integration.channel.nullChannel.errorRate.mean": 0,
"integration.channel.nullChannel.errorRate.max": 0,
"integration.channel.nullChannel.errorRate.min": 0,
"integration.channel.nullChannel.errorRate.stdev": 0,
"integration.channel.nullChannel.errorRate.count": 0,
"integration.channel.nullChannel.sendCount": 0,
"integration.channel.nullChannel.sendRate.mean": 0,
"integration.channel.nullChannel.sendRate.max": 0,
"integration.channel.nullChannel.sendRate.min": 0,
"integration.channel.nullChannel.sendRate.stdev": 0,
"integration.channel.nullChannel.sendRate.count": 0,
"integration.channel.springCloudBusOutput.errorRate.mean": 0,
"integration.channel.springCloudBusOutput.errorRate.max": 0,
"integration.channel.springCloudBusOutput.errorRate.min": 0,
"integration.channel.springCloudBusOutput.errorRate.stdev": 0,
"integration.channel.springCloudBusOutput.errorRate.count": 0,
"integration.channel.springCloudBusOutput.sendCount": 0,
"integration.channel.springCloudBusOutput.sendRate.mean": 0,
"integration.channel.springCloudBusOutput.sendRate.max": 0,
"integration.channel.springCloudBusOutput.sendRate.min": 0,
"integration.channel.springCloudBusOutput.sendRate.stdev": 0,
"integration.channel.springCloudBusOutput.sendRate.count": 0,
"integration.handler._org.springframework.integration.errorLogger.handler.duration.mean":
0,
"integration.handler._org.springframework.integration.errorLogger.handler.duration.max":
0,
"integration.handler._org.springframework.integration.errorLogger.handler.duration.min":
0,
"integration.handler._org.springframework.integration.errorLogger.handler.duration.stdev":
0,
"integration.handler._org.springframework.integration.errorLogger.handler.duration.count":
0,
"integration.handler._org.springframework.integration.errorLogger.handler.activeCount":
0,
"integration.handlerCount": 1,
"integration.channelCount": 5,
"integration.sourceCount": 0,
"httpsessions.max": -1,
"httpsessions.active": 0,
"datasource.primary.active": 0,
"datasource.primary.usage": 0 }
Code flow doesn't even go to the method(tried to use debugger).
The problem with only this newly created endpoint. Last error was
Full authentication is required to access this resource
until I wrote the piece of configuration:
management:
security:
enabled: false
I use
springBootVersion = '1.5.3.RELEASE'
springCloudVersion = 'Dalston.RELEASE'
The issue was with Spring Cloud MetricsInterceptorConfiguration.
As far as I understood, on each endpoint you can add suffix-path /metrics to see the metrics for this endpoint provided by Spring Cloud. So it just intercepted my mapping :)
I solved this by adding the following configuration to bootstrap.yml:
endpoints:
metrics:
enabled: false

Is it possible to store Arduino data for sketch in plain text onboard Arduino?

I created this arduino sketch and it works fine, what happens is you hold a button down and a pattern of lights plays. You can see my patterns at the bottom. Each button has its own pattern to play when its held.
So this works fine, but I have a question. I'm uneasy about this because I feel that its better practice to keep my patterns outside the program. I want to know, can I store the patterns in a text file that also gets loaded onto the arduino? Is there anyway to put the patterns in a text file, and just read them all onboard the arduino?
const int buttonPin[5] = {8,9,10,11,12};
const int LEDPin[5] = {2,3,4,5,6};
int timer =0;
int millisBegin=0;
boolean reset=true;
boolean run[5] = {false,false,false,false,false};
boolean buttonOn = false;
void setup(){
Serial.begin(57600);
pinMode(buttonPin[0], INPUT);
pinMode(buttonPin[1], INPUT);
pinMode(buttonPin[2], INPUT);
pinMode(buttonPin[3], INPUT);
pinMode(buttonPin[4], INPUT);
pinMode(LEDPin[0], OUTPUT);
pinMode(LEDPin[1], OUTPUT);
pinMode(LEDPin[2], OUTPUT);
pinMode(LEDPin[3], OUTPUT);
pinMode(LEDPin[4], OUTPUT);
}
void loop()
{
for (int x=0; x<6; x++)
{
if (digitalRead(buttonPin[x]) == HIGH)
{
run[x] = true;
}
}
if (run[0] == true)
{
buttonOn = pattern1();
if (buttonOn == false)
{
run[0] = false;
}
}
if (run[1] == true)
{
buttonOn = pattern2();
if (buttonOn == false)
{
run[1] = false;
}
}
if (run[2] == true)
{
buttonOn = pattern3();
if (buttonOn == false)
{
run[2] = false;
}
}
if (run[3] == true)
{
buttonOn = pattern4();
if (buttonOn == false)
{
run[3] = false;
}
}
if (run[4] == true)
{
buttonOn = pattern5();
if (buttonOn == false)
{
run[4] = false;
}
}
}
boolean light(int button, int pattern[][6])
{
while (digitalRead(buttonPin[button])==LOW)
{
reset = true;
for (int x=0; x<5; x++){
digitalWrite(LEDPin[x],LOW);
}
buttonOn = false;
return buttonOn;
}
while (digitalRead(buttonPin[button])==HIGH)
{
if (reset == true)
{
millisBegin = millis();
reset = false;
Serial.println("reset!");
}
timer = millis() - millisBegin;
for (int x=0; x<10; x++) //Pattern amount
{
for (int y=0; y<5; y++) //Lights
{
//if else runs pattern with correct time code
if (timer>pattern[x][5]&&timer<pattern[x+1][5])
{
if (pattern[x][y]==1)
{
digitalWrite(LEDPin[y], HIGH);
}
else
{
digitalWrite(LEDPin[y], LOW);
}
}
}
}
Serial.println(timer);
if (timer > pattern[10][5]){
reset = true;
Serial.println("Over timer!");
}
}
}
boolean pattern1()
{
int pattern[11][6] = {
{0, 0, 0, 0, 0, 100}, //0
{1, 1, 0, 1, 1, 1200}, //1
{0, 0, 1, 0, 0, 2200}, //2
{1, 1, 0, 1, 1, 3200}, //3
{0, 0, 0, 0, 0, 4200}, //4
{1, 1, 1, 1, 1, 5000}, //5
{0, 0, 1, 0, 0, 6000}, //6
{1, 0, 0, 0, 0, 7000}, //7
{0, 1, 0, 1, 1, 8000}, //8arduin
{0, 0, 1, 0, 1, 9000}, //9
{0, 0, 0, 0, 0, 10000}}; //
buttonOn = light(0,pattern);
return buttonOn;
}
boolean pattern2()
{
int pattern[11][6] = {
{1, 0, 1, 0, 0, 100}, //0
{0, 1, 1, 0, 1, 180}, //1
{1, 0, 0, 0, 0, 230}, //2
{0, 1, 0, 1, 1, 340}, //3
{1, 0, 0, 1, 0, 450}, //4
{0, 0, 1, 1, 1, 500}, //5
{0, 0, 1, 0, 0, 550}, //6
{1, 0, 0, 0, 0, 600}, //7
{0, 1, 0, 1, 1, 680}, //8
{0, 0, 1, 0, 1, 800}, //9
{0, 0, 0, 0, 0, 900}}; //
buttonOn = light(1,pattern);
return buttonOn;
}
boolean pattern3()
{
int pattern[11][6] = {
{1, 1, 1, 1, 1, 100}, //0
{0, 0, 0, 0, 0, 180}, //1
{1, 1, 1, 1, 1, 230}, //2
{0, 0, 0, 0, 0, 340}, //3
{1, 1, 1, 1, 1, 450}, //4
{0, 0, 0, 0, 0, 500}, //5
{1, 1, 1, 1, 1, 550}, //6
{0, 0, 0, 0, 0, 600}, //7
{1, 1, 1, 1, 1, 680}, //8
{0, 0, 0, 0, 0, 800}, //9
{0, 0, 0, 0, 0, 810}}; //
buttonOn = light(2,pattern);
return buttonOn;
}
boolean pattern4()
{
int pattern[11][6] = {
{0, 0, 0, 0, 0, 100}, //0
{0, 0, 0, 0, 1, 500}, //1
{0, 0, 0, 1, 1, 800}, //2
{0, 0, 1, 1, 1, 900}, //3
{1, 1, 1, 1, 1, 1000}, //4
{1, 1, 1, 1, 1, 1100}, //5
{1, 1, 1, 1, 0, 1200}, //6
{1, 1, 1, 0, 0, 1300}, //7
{1, 1, 0, 0, 0, 1400}, //8
{1, 0, 0, 0, 0, 1500}, //9
{0, 0, 0, 0, 0, 1600}}; //
buttonOn = light(3,pattern);
return buttonOn;
}
boolean pattern5()
{
int pattern[11][6] = {
{0, 1, 0, 1, 0, 100}, //0
{1, 0, 1, 0, 1, 500}, //1
{0, 1, 0, 1, 0, 800}, //2
{1, 0, 1, 0, 1, 900}, //3
{0, 1, 0, 1, 0, 1000}, //4
{1, 0, 1, 0, 1, 1100}, //5
{0, 1, 0, 1, 0, 1200}, //6
{1, 0, 1, 0, 1, 1300}, //7
{0, 1, 0, 1, 0, 1400}, //8
{1, 0, 1, 0, 1, 1500}, //9
{0, 1, 0, 1, 0, 1600}}; //
buttonOn = light(4,pattern);
return buttonOn;
}
The Arduino boards do not have external storage devices where files can be stored. Of course there are shields with a SD card slot which you can add to your device. This would be overkill however.
But the Arduino has a builtin EEPROM which you can read/write using the EEPROM library.
My suggestion would be:
Extend your program to read and write to USB via Serial. You can then invent some simple text-based commands which allow you to send new patterns to the Arduino.
When the Arduino receives new patterns, it stores them in the EEPROM.
In normal operation mode the Arduino reads the patterns from EEPROM and displays them.
This way you can use your Arduino "standalone" and program it ad-hoc using any computer.

Resources