In this case, the second argument is used to encode an array index, making it easy to use one alarm handler for several different alarms.
Often, the second argument is used as a pointer to some object that contains information useful to the alarm handler -- but that is completely up to the sketch designer.
// Alarm sketch 3: Advanced alarm techniques - The 'two argument' alarm handler const u32 LEDS = 7; // To size our arrays and loops u32 periods[LEDS]; // How fast each is blinking u32 alarms[LEDS]; // The alarm index for each u32 pins[LEDS] = { // The actual pin numbers of the LEDs BODY_RGB_RED_PIN, BODY_RGB_GREEN_PIN, BODY_RGB_BLUE_PIN, NORTH_LED_PIN, SOUTH_LED_PIN, EAST_LED_PIN, WEST_LED_PIN }; // A 'two argument' alarm handler. void allAlarmHandler(u32 when, void * arg) { u32 index = (u32) arg; // We know arg is 'really' a u32, because that's // what we passed in to Alarms.create, below. ledToggle(pins[index]); // Toggle whatever pin we're dealing with Alarms.set(alarms[index], when+periods[index]); // And reschedule whichever alarm } void setup() { for (u32 i = 0; i < LEDS; ++i) { // Create all the alarms // Here we use the 'two argument' form of Alarms.create. The // second argument officially must be a 'void *' -- a pointer to nothing? -- // but actually we can 'sneak in' any value we want, so long as it fits // in 32 bits. Here, we pass in the appropriate array index for each // particular alarm, allowing us to reuse the single handler, above. alarms[i] = Alarms.create(allAlarmHandler,(void*) i); periods[i] = random(100,1000); // Pick random periods from 0.1sec-1.0sec Alarms.set(alarms[i], 0); // Start everybody off right away. } } void loop() { /* Nothing to do */ }